Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade generator script #15

Merged
merged 4 commits into from
Apr 3, 2021
Merged

Conversation

Gnimuc
Copy link
Member

@Gnimuc Gnimuc commented Mar 30, 2021

No description provided.

@wsphillips
Copy link
Collaborator

Wow! Thanks for the PR. You sure did a lot in Clang.jl. And the defaults definitely produce cleaner results than before!

Is there an intended pattern for creating custom passes/exceptions during codegen? It wasn't always pretty, but previously I would write helpers to do some special handling for library-specific things. I want to modify code generation for specific function symbol names/patterns. Before I would do that by writing my own wrap! methods, where I would include some extra pattern matching. It looks like the analogous function is now called emit! ?

@Gnimuc
Copy link
Member Author

Gnimuc commented Mar 31, 2021

The new generator exposes a DAG of the C code, the data structure is like:

"""
    ExprNode{T<:AbstractExprNodeType,S<:CLCursor}
An expression node in the expression DAG.
"""
struct ExprNode{T<:AbstractExprNodeType,S<:CLCursor}
    id::Symbol
    type::T
    cursor::S
    exprs::Vector{Expr}
    adj::Vector{Int}
end

"""
    ExprDAG
An expression DAG.
"""
struct ExprDAG
    nodes::Vector{ExprNode}
    tags::Dict{Symbol,Int}
    ids::Dict{Symbol,Int}
    ids_extra::Dict{Symbol,AbstractJuliaType}
end
ExprDAG(nodes; ids_extra=EXTRA_DEFINITIONS) = ExprDAG(nodes, Dict(), Dict(), ids_extra)

If you'd like to rewrite the generated Julia expression for certain nodes, you could do something like this.

BTW, the implementation of create_context itself) is also pretty straightforward, it's not hard to build the context from scratch with custom passes. The current design may need to be tweaked for supporting new features, so any suggestions would be highly appreciated!

@wsphillips
Copy link
Collaborator

wsphillips commented Apr 2, 2021

@Gnimuc could you enable edits from maintainers? I have revisions I want to propose. Edit: nevermind CLI typo

Comment on lines +340 to +350
function PlotLine(label_id, values::AbstractArray{Cfloat}, count::Integer, xscale::Real, x0::Real, offset::Integer, stride::Integer)
ccall((:ImPlot_PlotLineFloatPtrInt, libcimplot), Cvoid, (Cstring, Ref{Cfloat}, Cint, Cdouble, Cdouble, Cint, Cint), label_id, values, count, xscale, x0, offset, stride)
end

function PlotLine(label_id, values::AbstractArray{Cdouble}, count::Integer, xscale::Real, x0::Real, offset::Integer, stride::Integer)
ccall((:ImPlot_PlotLinedoublePtrInt, libcimplot), Cvoid, (Cstring, Ref{Cdouble}, Cint, Cdouble, Cdouble, Cint, Cint), label_id, values, count, xscale, x0, offset, stride)
end

function PlotLine(label_id, values::AbstractArray{ImS8}, count::Integer, xscale::Real, x0::Real, offset::Integer, stride::Integer)
ccall((:ImPlot_PlotLineS8PtrInt, libcimplot), Cvoid, (Cstring, Ref{ImS8}, Cint, Cdouble, Cdouble, Cint, Cint), label_id, values, count, xscale, x0, offset, stride)
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Gnimuc @sairus7 @yamen I wrote an extra pass for all PlotXXX functions. They are now typed loosely so we can let multiple dispatch do the work for us. Still need to clean up the rest, but the idea should be clear. I would plan to rebase the changes happening in #14 onto the updated wrappers here, thereby making any kind of symbol lookup unnecessary. It should also make it easier to finish writing the demo.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any default value handling for count, xscale, x0, offset, stride? Seems like it remains the only reason to have helper functions.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible--I even left some commented out sections in the generator script that provide examples of how to do it. However, I'm not sure whether it's worth it to take it that far. I may consider taking it an extra step in the future. For now, this change (along with some auto exporting Clang can now include) will reduce the vast majority of the work anyhow. (e.g. since everything is overloaded, adding defaults to match the behavior of C++ is just a 1-2 line wrapper)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nice! Agree it may not be immediately worth adding defaults and other conveniences into the wrapper scripts as there may be nicer / cleaner ways of managing that in Julia directly.

@yamen
Copy link

yamen commented Apr 2, 2021

@wsphillips @Gnimuc I think it's important we try this new generator / wrapper against the latest cimplot, as this includes both the upgrade to 0.9, and (far more importantly) the implot_internal.h header also. This header is really important for custom GUI work, and would be another stress test for the new generator.

@Gnimuc the binary builder that generates the fully merged Julia binary is here (https://github.com/yamen/CImGui_jll-builder) or can be pointed directly to the binaries here (https://github.com/yamen/CImGui_jll.jl) although note it's only built for Windows atm as I had issues with Mac building locally.

@Gnimuc
Copy link
Member Author

Gnimuc commented Apr 3, 2021

@Gnimuc the binary builder that generates the fully merged Julia binary is here (https://github.com/yamen/CImGui_jll-builder) or can be pointed directly to the binaries here (https://github.com/yamen/CImGui_jll.jl) although note it's only built for Windows atm as I had issues with Mac building locally.

no worries, after JuliaImGui/CImGui.jl#46 is merged(hopefully tomorrow), we will have a pure CImGui_jll.

@wsphillips wsphillips merged commit fab384e into JuliaImGui:master Apr 3, 2021
@Gnimuc Gnimuc deleted the up-generator branch April 4, 2021 01:39
@sonoro1234
Copy link

There are more recent additions to cimplot as using ImPlotTime as UDT

@sairus7
Copy link
Collaborator

sairus7 commented Apr 9, 2021

Also, in the current version of generated libcimplot.jl there are differences in bunch of Get... methods or that have pOut arguments like this:

function GetPlotLimits(pOut, y_axis)
    ccall((:ImPlot_GetPlotLimits, libcimplot), Cvoid, (Ptr{ImPlotLimits}, ImPlotYAxis), pOut, y_axis)
end

So I cannot just write limits = GetPlotLimits(0) and this is very uncomfortable.

Also, I notices some helpers for such functions:

function GetPlotSize()
    out = Ref{ImVec2}()
    LibCImPlot.GetPlotSize(out)
    return out[]
end

Looks like we should add more such helpers for these functions, OR maybe generator script can be tweaked further?
Is applies to:

GetPlotPos(pOut)
GetPlotSize(pOut)
GetPlotMousePos(pOut, y_axis)
GetPlotLimits(pOut, y_axis)
GetPlotQuery(pOut, y_axis)
GetLastItemColor(pOut)
GetColormapColor(pOut, index)
PixelsToPlotVec2(pOut, pix, y_axis)
PixelsToPlotFloat(pOut, x, y, y_axis)
PlotToPixelsPlotPoInt(pOut, plt, y_axis)
PlotToPixelsdouble(pOut, x::Real, y::Real, y_axis)
LerpColormap(pOut, t)
NextColormapColor(pOut)

@sonoro1234
Copy link

Looks like we should add more such helpers for these functions, OR maybe generator script can be tweaked further?

Ideally this helpers should be generated automatically for all functions in definitions.json having the field nonUDT

@Gnimuc
Copy link
Member Author

Gnimuc commented Apr 9, 2021

Also, I notices some helpers for such functions:

function GetPlotSize()
    out = Ref{ImVec2}()
    LibCImPlot.GetPlotSize(out)
    return out[]
end

Looks like we should add more such helpers for these functions, OR maybe generator script can be tweaked further?
Is applies to:

GetPlotPos(pOut)
GetPlotSize(pOut)
GetPlotMousePos(pOut, y_axis)
GetPlotLimits(pOut, y_axis)
GetPlotQuery(pOut, y_axis)
GetLastItemColor(pOut)
GetColormapColor(pOut, index)
PixelsToPlotVec2(pOut, pix, y_axis)
PixelsToPlotFloat(pOut, x, y, y_axis)
PlotToPixelsPlotPoInt(pOut, plt, y_axis)
PlotToPixelsdouble(pOut, x::Real, y::Real, y_axis)
LerpColormap(pOut, t)
NextColormapColor(pOut)

CImGui.jl uses a style in which all functions in LibCImGui are mapped exactly the same as those C API and all helper wrappers are only defined in CImGui but not exported. For those who prefer to use original C API(this is often the case when porting a C codebase), using LibCImGui is enough. OTOH, those who would like to write in a Julian way, CImGui.JuliaStyleAPI can be used.

I just want to point out that, it's really annoying if the API provided by the wrapper library is slightly different from the original one in a random way and without any docs(like the one in JuliaGL/GLFW.jl#177). It's really frustrating to remember two sets of APIs at the same time.

@sonoro1234
Copy link

sonoro1234 commented Apr 9, 2021

all helper wrappers are only defined in CImGui but not exported

I meant that this helper wrappers can be generated automatically for nonUDT functions.

It's really frustrating to remember two sets of APIs at the same time

In LuaJIT-ImGui there are C API and helpers (for taking care of defaults, nonUDT, methods from classes, etc). Users are expected to use only helpers (althought direct C API calls can be done if prefered) because they are more similar to cpp imgui usage and dont have to worry about strange overloading names in functions.

@Gnimuc
Copy link
Member Author

Gnimuc commented Apr 9, 2021

@sonoro1234 sorry, I was replying to @sairus7's comment. :)

@Gnimuc
Copy link
Member Author

Gnimuc commented Apr 9, 2021

As for the auto-generating, I think we could do some analysis on the generated Julia AST to produce those helper functions. This may need some support on the Clang.jl's side, but since C has no construct of marking a function argument as "output", the only thing we can rely on is probably the argument name.

@sairus7
Copy link
Collaborator

sairus7 commented Apr 9, 2021

Maybe first argument name and also pointer or reference type.
I'm not sure if I listed all such methods, but if so, we can add those helpers manually for now.

@Gnimuc
Copy link
Member Author

Gnimuc commented Apr 9, 2021

Yeah, adding patches manually to epilogue.jl is definitely the fastest way.

@sairus7
Copy link
Collaborator

sairus7 commented Apr 9, 2021

Oh, and also void return type.

Yeah, adding patches manually to epilogue.jl is definitely the fastest way.

I already added those helpers for my personal project, so I doubt it is the fastest way :)

@sairus7
Copy link
Collaborator

sairus7 commented Apr 9, 2021

I don't know why, but this wrapper works fine

function GetPlotSize_()
    out = Ref{ImPlot.LibCImPlot.ImVec2}()
    ImPlot.LibCImPlot.GetPlotSize(out)
    return out[]
end

And this throws error exception = UndefRefError: access to undefined reference:

function GetPlotLimits_(y_axis)
    out = Ref{ImPlot.LibCImPlot.ImPlotLimits}()
    ImPlot.LibCImPlot.GetPlotLimits(out, y_axis)
    return out[]
end

@Gnimuc
Copy link
Member Author

Gnimuc commented Apr 9, 2021

@sairus7 ImPlotLimits is a mutable struct and there is no init value.

@sonoro1234
Copy link

sonoro1234 commented Apr 9, 2021

but since C has no construct of marking a function argument as "output", the only thing we can rely on is probably the argument name.

forgive my insistence but all can worked with definitions.json: if stname is not "" or "ImGui" the function belongs to a struct and the first argument will be the struct, if nonUDT field exists then the first argument (or the second if the function belongs to a struct) is the out argument to be wrapped in the helper functions. (https://github.com/cimgui/cimgui#usage)

@wsphillips
Copy link
Collaborator

My intention has been to manually sort it out for now since there's not (yet) an insane number of cases where we need to do it. We can consider taking @sonoro1234 advice and fuse some of the json output from cimgui with our Clang.jl generator script.

P.S. On a complete side note: Viktor @sairus7 Victor @sonoro1234 Wiktor @wsphillips nice coincidence 😆

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants