mirror of
https://github.com/ocornut/imgui.git
synced 2025-04-07 14:29:40 +00:00
More thoroughly parse arguments and defaults
This commit is contained in:
parent
e26b91dcd0
commit
f61b72728e
2 changed files with 193 additions and 55 deletions
|
@ -40,7 +40,7 @@ class WrapperClass
|
|||
when 'Begin', 'BeginChild'
|
||||
'IsContentVisible'
|
||||
else
|
||||
'IsOpen' if m[:type] == 'bool'
|
||||
'IsOpen' if m[:type] == %w{bool}
|
||||
end
|
||||
|
||||
puts <<EOT
|
||||
|
@ -48,7 +48,7 @@ class WrapperClass
|
|||
#{INDENT}{
|
||||
EOT
|
||||
if @state_var
|
||||
puts "#{INDENT * 2}#{m[:type]} #{@state_var};"
|
||||
puts "#{INDENT * 2}#{m[:type].join('')} #{@state_var};"
|
||||
puts
|
||||
end
|
||||
end
|
||||
|
@ -79,62 +79,157 @@ EOT
|
|||
end
|
||||
end
|
||||
|
||||
def is_space(token)
|
||||
token =~ /^\s+/
|
||||
end
|
||||
|
||||
def first_non_space(tokens)
|
||||
tokens.find { |token| !is_space(token) }
|
||||
end
|
||||
|
||||
def skip_spaces(tokens)
|
||||
tokens.shift while is_space(tokens.first)
|
||||
end
|
||||
|
||||
def parse_until(tokens, stop_token)
|
||||
parsed = []
|
||||
|
||||
while first_non_space(tokens) != stop_token
|
||||
token = tokens.shift
|
||||
fail "End of tokens while looking for #{stop_token}" unless token
|
||||
parsed << token
|
||||
end
|
||||
skip_spaces(tokens)
|
||||
tokens.shift
|
||||
|
||||
parsed
|
||||
end
|
||||
|
||||
def chop_space(tokens)
|
||||
tokens.pop if is_space(tokens.last)
|
||||
end
|
||||
|
||||
def parse_method(line)
|
||||
m = {}
|
||||
|
||||
tokens = line.scan(/\w+|\s+|\.\.\.|\/\/.*$|./)
|
||||
skip_spaces(tokens)
|
||||
|
||||
return nil unless tokens.shift == 'IMGUI_API'
|
||||
skip_spaces(tokens)
|
||||
|
||||
type_and_name = parse_until(tokens, '(')
|
||||
m[:name] = type_and_name.pop
|
||||
chop_space(type_and_name)
|
||||
m[:type] = type_and_name
|
||||
|
||||
return nil unless m[:name].match(/^(Begin|Push|TreeNode)/)
|
||||
|
||||
m[:args] = [[]]
|
||||
m[:argnames] = []
|
||||
paren_level = 0
|
||||
in_default = false
|
||||
loop do
|
||||
token = tokens.shift
|
||||
fail "End of tokens while parsing argument list" unless token
|
||||
|
||||
case token
|
||||
when '('
|
||||
paren_level+= 1
|
||||
when ')'
|
||||
break if paren_level == 0
|
||||
paren_level-= 1
|
||||
when ','
|
||||
if paren_level == 0
|
||||
m[:args] << []
|
||||
in_default = false
|
||||
next
|
||||
end
|
||||
end
|
||||
|
||||
if paren_level == 0 && !in_default
|
||||
next_non_space = first_non_space(tokens)
|
||||
|
||||
if next_non_space == ')' || next_non_space == ',' || next_non_space == '='
|
||||
m[:argnames] << token
|
||||
in_default = (next_non_space == '=')
|
||||
end
|
||||
end
|
||||
|
||||
m[:args][-1] << token
|
||||
end
|
||||
|
||||
m[:attrs] = parse_until(tokens, ';')
|
||||
|
||||
skip_spaces(tokens)
|
||||
m[:rest] = tokens
|
||||
|
||||
m
|
||||
end
|
||||
|
||||
current_class = nil
|
||||
|
||||
header_file = File.open("../../imgui.h")
|
||||
header_file.each_line do |line|
|
||||
break if line.match(/^}\s*\/\/\s*namespace ImGui$/i)
|
||||
|
||||
line.match(/^\s*IMGUI_API\s+(?<type>[\w\s]+\w)\s+(?<name>\w*)\((?<args>[^)]+)\)(?<attrs>[^;]*);(?<rest>.*)$/) do |m|
|
||||
next unless m[:name].match(/^(Begin|Push|Tree)/)
|
||||
m = parse_method(line)
|
||||
next unless m
|
||||
|
||||
argnames = m[:args].split(/,\s*/).map do |arg|
|
||||
arg = arg.split(/\s*=\s*/, 2).first
|
||||
arg.split(/[ \*]/).last
|
||||
end
|
||||
next unless m[:name].match(/^(Begin|Push|Tree)/)
|
||||
|
||||
# Check for obsolete
|
||||
if m[:name] == 'Begin' &&
|
||||
(argnames == %w{name p_open size_on_first_use bg_alpha_override flags} ||
|
||||
argnames == %w{items_count items_height})
|
||||
next
|
||||
end
|
||||
$stderr.puts m.inspect if $-d
|
||||
|
||||
$stderr.puts m.inspect if $-d
|
||||
|
||||
fail "Return value #{m[:type]} is not bool or void" unless %w{bool void}.include?(m[:type])
|
||||
|
||||
if !current_class || current_class.name != m[:name]
|
||||
if current_class
|
||||
current_class.close
|
||||
puts
|
||||
end
|
||||
|
||||
current_class = WrapperClass.new(m)
|
||||
end
|
||||
|
||||
attrs = m[:attrs].gsub(/IM_FMT(ARGS|LIST)\(\d+\)/) do |a|
|
||||
a.sub(/\d+/) { |index| (index.to_i + 1).to_s }
|
||||
end
|
||||
|
||||
print "#{INDENT * 2}#{current_class.class_name}(#{m[:args]})#{attrs} { "
|
||||
|
||||
use_varargs = false
|
||||
if argnames.last == '...'
|
||||
argnames[-1] = 'ap'
|
||||
use_varargs = true
|
||||
print "va_list ap; va_start(ap, fmt); "
|
||||
end
|
||||
|
||||
print "#{current_class.state_var} = " if current_class.state_var
|
||||
|
||||
print "ImGui::#{m[:name]}"
|
||||
print 'V' if use_varargs
|
||||
print "(#{argnames.join(', ')}); "
|
||||
print 'va_end(ap); ' if use_varargs
|
||||
|
||||
puts '}'
|
||||
# Check for obsolete
|
||||
if m[:name] == 'Begin' &&
|
||||
(m[:argnames] == %w{name p_open size_on_first_use bg_alpha_override flags} ||
|
||||
m[:argnames] == %w{items_count items_height})
|
||||
next
|
||||
end
|
||||
|
||||
fail "Return value #{m[:type]} is not bool or void" unless [%w{bool}, %w{void}].include?(m[:type])
|
||||
|
||||
if !current_class || current_class.name != m[:name]
|
||||
if current_class
|
||||
current_class.close
|
||||
puts
|
||||
end
|
||||
|
||||
current_class = WrapperClass.new(m)
|
||||
end
|
||||
|
||||
shift_index = false
|
||||
attrs = m[:attrs].map do |attr|
|
||||
case attr
|
||||
when /^IM_FMT(ARGS|LIST)$/
|
||||
shift_index = true
|
||||
when /^\d+/
|
||||
if shift_index
|
||||
attr = (attr.to_i + 1).to_s
|
||||
shift_index = false
|
||||
end
|
||||
end
|
||||
attr
|
||||
end.join('')
|
||||
|
||||
args = m[:args].map { |argparts| argparts.join('') }.join(',')
|
||||
print "#{INDENT * 2}#{current_class.class_name}(#{args})#{attrs} { "
|
||||
|
||||
use_varargs = false
|
||||
if m[:argnames].last == '...'
|
||||
m[:argnames][-1] = 'ap'
|
||||
use_varargs = true
|
||||
print "va_list ap; va_start(ap, fmt); "
|
||||
end
|
||||
|
||||
print "#{current_class.state_var} = " if current_class.state_var
|
||||
|
||||
print "ImGui::#{m[:name]}"
|
||||
print 'V' if use_varargs
|
||||
print "(#{m[:argnames].join(', ')}); "
|
||||
print 'va_end(ap); ' if use_varargs
|
||||
|
||||
puts '}'
|
||||
end
|
||||
|
||||
current_class.close if current_class
|
||||
|
|
|
@ -26,8 +26,8 @@ namespace ImScoped
|
|||
{
|
||||
bool IsContentVisible;
|
||||
|
||||
Child(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0) { IsContentVisible = ImGui::BeginChild(str_id, size, 0); }
|
||||
Child(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0) { IsContentVisible = ImGui::BeginChild(id, size, 0); }
|
||||
Child(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0) { IsContentVisible = ImGui::BeginChild(str_id, size, border, flags); }
|
||||
Child(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0) { IsContentVisible = ImGui::BeginChild(id, size, border, flags); }
|
||||
~Child() { ImGui::EndChild(); }
|
||||
|
||||
explicit operator bool() const { return IsContentVisible; }
|
||||
|
@ -93,6 +93,14 @@ namespace ImScoped
|
|||
IMGUI_DELETE_MOVE_COPY(ButtonRepeat);
|
||||
};
|
||||
|
||||
struct Group
|
||||
{
|
||||
Group() { ImGui::BeginGroup(); }
|
||||
~Group() { if () ImGui::EndGroup(); }
|
||||
|
||||
IMGUI_DELETE_MOVE_COPY(Group);
|
||||
};
|
||||
|
||||
struct ID
|
||||
{
|
||||
ID(const char* str_id) { ImGui::PushID(str_id); }
|
||||
|
@ -170,13 +178,28 @@ namespace ImScoped
|
|||
IMGUI_DELETE_MOVE_COPY(TreeNodeExV);
|
||||
};
|
||||
|
||||
struct TreePush
|
||||
struct MainMenuBar
|
||||
{
|
||||
TreePush(const char* str_id) { ImGui::TreePush(str_id); }
|
||||
TreePush(const void* ptr_id = NULL) { ImGui::TreePush(ptr_id); }
|
||||
~TreePush() { ImGui::TreePop(); }
|
||||
bool IsOpen;
|
||||
|
||||
IMGUI_DELETE_MOVE_COPY(TreePush);
|
||||
MainMenuBar() { IsOpen = ImGui::BeginMainMenuBar(); }
|
||||
~MainMenuBar() { if (IsOpen) ImGui::EndMainMenuBar(); }
|
||||
|
||||
explicit operator bool() const { return IsOpen; }
|
||||
|
||||
IMGUI_DELETE_MOVE_COPY(MainMenuBar);
|
||||
};
|
||||
|
||||
struct MenuBar
|
||||
{
|
||||
bool IsOpen;
|
||||
|
||||
MenuBar() { IsOpen = ImGui::BeginMenuBar(); }
|
||||
~MenuBar() { if (IsOpen) ImGui::EndMenuBar(); }
|
||||
|
||||
explicit operator bool() const { return IsOpen; }
|
||||
|
||||
IMGUI_DELETE_MOVE_COPY(MenuBar);
|
||||
};
|
||||
|
||||
struct Menu
|
||||
|
@ -191,6 +214,14 @@ namespace ImScoped
|
|||
IMGUI_DELETE_MOVE_COPY(Menu);
|
||||
};
|
||||
|
||||
struct Tooltip
|
||||
{
|
||||
Tooltip() { ImGui::BeginTooltip(); }
|
||||
~Tooltip() { if () ImGui::EndTooltip(); }
|
||||
|
||||
IMGUI_DELETE_MOVE_COPY(Tooltip);
|
||||
};
|
||||
|
||||
struct Popup
|
||||
{
|
||||
bool IsOpen;
|
||||
|
@ -263,6 +294,18 @@ namespace ImScoped
|
|||
IMGUI_DELETE_MOVE_COPY(DragDropSource);
|
||||
};
|
||||
|
||||
struct DragDropTarget
|
||||
{
|
||||
bool IsOpen;
|
||||
|
||||
DragDropTarget() { IsOpen = ImGui::BeginDragDropTarget(); }
|
||||
~DragDropTarget() { if (IsOpen) ImGui::EndDragDropTarget(); }
|
||||
|
||||
explicit operator bool() const { return IsOpen; }
|
||||
|
||||
IMGUI_DELETE_MOVE_COPY(DragDropTarget);
|
||||
};
|
||||
|
||||
struct ClipRect
|
||||
{
|
||||
ClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect) { ImGui::PushClipRect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect); }
|
||||
|
|
Loading…
Add table
Reference in a new issue