Skip to content

Commit

Permalink
Move extension_api task to extension_api.rb which extconf.rb it…
Browse files Browse the repository at this point in the history
…self `require`s
  • Loading branch information
ParadoxV5 committed Apr 27, 2024
1 parent a1673ec commit a915883
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 79 deletions.
81 changes: 5 additions & 76 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,82 +12,11 @@ CLOBBER << OUT = 'generated'

# C
Rake::ExtensionTask.new 'godot_rb' do|ext|
CLEAN << GLUE_C = File.join(ext.ext_dir, 'variant_types.c')
GLUE_C_ERB = "#{GLUE_C}.erb"
ext.lib_dir = OUT
ext.source_pattern = '*.c{,.erb}'
ext.source_pattern = '*.{c,h}{,.erb}'
ext.extra_sources.add File.join(ext.ext_dir, '*.rb'), 'ext/include/**/*.h', 'ext/include/godot/extension_api_with_docs.json'
ext.no_native = true
end

# Glue Code Entry Task
GLUE_RB = %w[core editor].to_h { [_1, File.join(OUT, "#{_1}.rb")] }
glue = GLUE_RB.values.push File.join(OUT, 'godot.rbs'), GLUE_C
glue.each { file _1 => :extension_api } # Each task executes at most once
desc 'Generate glue code'
task(glue:)


# Common Glue Code Generator Task
EXTENSION_API = 'ext/include/godot/extension_api_with_docs.json'
task :extension_api => [GLUE_C_ERB, EXTENSION_API, OUT] do
require 'json'
require 'erb'
puts "> loading #{EXTENSION_API}"
json = JSON.load_file EXTENSION_API
N_IMMEDIATES = 4

puts '| processing variant sizes'
string_name_default_size = 0
build_configurations = json.delete('builtin_class_sizes').to_h do|config|
sizes = config.fetch('sizes').drop(N_IMMEDIATES).to_h(&:values)
string_name_size = sizes.fetch 'StringName'
string_name_default_size = string_name_size if string_name_size > string_name_default_size
[
config.fetch('build_configuration'),
sizes.map do|name, size|
"godot_rb_cVariant_sizes[gdvt#{name}] = #{size};"
end.join("\n")
]
end

puts '| processing variant classes'
json.delete('builtin_classes')
.drop(N_IMMEDIATES)
.to_h { _1.values_at 'name', 'has_destructor' } => type_has_destructors
type_has_destructors['Object'] = false # not included in `builtin_classes`

json.delete('classes')
.find { _1['name'] == 'OS' }
.delete('methods')
.find { _1['name'] == 'has_feature' }
.fetch('hash') => hash_OS_has_feature

puts "< generating #{GLUE_C}"
File.write GLUE_C, ERB.new(File.read GLUE_C_ERB).result_with_hash(
string_name_default_size:,
build_configurations:,
type_has_destructors:,
hash_OS_has_feature:
)

#TODO (creating empty files to prevent task reïnvoking)
touch(GLUE_RB.values, verbose:)
# files = GLUE_RB.transform_values do|path|
# File.open path, 'w'
# rescue => e
# warn e.full_message
# end
# begin
# json['classes'].each do|klass_data|
# files[klass_data['api_type']]&.then do|rb|
# klass_data['methods']&.each do|method_data|
# method_data['hash']&.then { _1 }
# end
# end
# end
# ensure
# files.each_value { _1&.close }
# end
CLEAN << File.join(ext.ext_dir, 'variant_types.c')
end


Expand Down Expand Up @@ -141,5 +70,5 @@ multitask dll_symlinks: libs.map {|name, lib_path|
}

# Entry Task
desc 'Build Godot.rb, complete with glue code, the `.gdextension` and Ruby DLL symlinks'
multitask default: %i[compile glue gdextension dll_symlinks]
desc 'Build Godot.rb, including symlinks for Ruby shared libraries'
multitask default: %i[compile gdextension dll_symlinks]
10 changes: 7 additions & 3 deletions ext/godot_rb/extconf.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
require 'mkmf'

include = File.expand_path '../../include/', __FILE__
find_header 'godot_rb.h', include
find_header 'godot/gdextension_interface.h', include
INCLUDE = File.expand_path '../../include/', __FILE__
def find_header!(header)
find_header header, INCLUDE or raise LoadError, "missing header:\t#{header}"
end
find_header! 'godot_rb.h'
find_header! 'godot/gdextension_interface.h'

require_relative 'extension_api'
create_makefile 'godot_rb'
63 changes: 63 additions & 0 deletions ext/godot_rb/extension_api.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
require 'json'
require 'erb'

EXTENSION_API = File.expand_path '../../include/godot/extension_api_with_docs.json', __FILE__
immediate_skips = 4

puts "> loading #{EXTENSION_API}"
json = JSON.load_file EXTENSION_API

puts '| processing variant sizes'
string_name_default_size = 0
build_configurations = json.delete('builtin_class_sizes').to_h do|config|
sizes = config.fetch('sizes').tap { _1.shift immediate_skips }.to_h(&:values)
string_name_size = sizes.fetch 'StringName'
string_name_default_size = string_name_size if string_name_size > string_name_default_size
[
config.fetch('build_configuration'),
sizes.map do|name, size|
"godot_rb_cVariant_sizes[gdvt#{name}] = #{size};"
end.join("\n")
]
end

puts '| processing variant classes'
type_has_destructors = json.delete('builtin_classes').tap do|it|
it.pop immediate_skips
end.to_h { _1.values_at 'name', 'has_destructor' }
type_has_destructors['Object'] = false # not included in `builtin_classes`

json.delete('classes')
.find { _1['name'] == 'OS' }
.delete('methods')
.find { _1['name'] == 'has_feature' }
.fetch('hash') => hash_OS_has_feature

variant_types_c = File.expand_path '../variant_types.c', __FILE__
puts "< generating #{variant_types_c}"
File.write(
variant_types_c,
ERB.new(File.read "#{variant_types_c}.erb").result_with_hash(
string_name_default_size:,
build_configurations:,
type_has_destructors:,
hash_OS_has_feature:
)
)

# files = %w[core editor].to_h { [_1, File.join(OUT, "#{_1}.rb")] }.transform_values do|path|
# File.open path, 'w'
# rescue => e
# warn e.full_message
# end
# begin
# json['classes'].each do|klass_data|
# files[klass_data['api_type']]&.then do|rb|
# klass_data['methods']&.each do|method_data|
# method_data['hash']&.then { _1 }
# end
# end
# end
# ensure
# files.each_value { _1&.close }
# end

0 comments on commit a915883

Please sign in to comment.