Closed FaresX closed 1 month ago
You could use PushID() / PopID()
.
function edit(insbuf::InstrBuffer, addr)
for qt in insbuf.quantities
CImGui.PushID(qt.name)
edit(qt, insbuf.instrnm, addr)
CImGui.PopID()
end
end
isvalidaddr = selectaddr in append!(collect.(keys.(values(instrbuffer)))...)
selectaddr = isvalidaddr ? selectaddr : ""
selectins in keys(default_insbufs) || push!(default_insbufs, selectins=>InstrBuffer(selectins))
insbuf = selectaddr == "" ? default_insbufs[selectins] : instrbuffer[selectins][selectaddr]
CImGui.PushID(string(selectins, selectaddr))
edit(insbuf, selectaddr)
CImGui.PopID()
I have tried it. There exists the same problem and I think it is not because of the IDs. When I do not select any addresses, there is no problem. Here, "instrbuffer" is a global variable in my module, and "default_insbufs" is a local variable inside a let block.
Please submit an MWE, I'm not responsible for debugging your incomplete code with such limited info.
I have fixed this issue, but I am not clear about the reason. According to your suggestion, I wrote the sample code below. When I follow the workflow that generates data remotely and fetches back, the problem will be reproduced. However, when all things happen locally, there will be no problem.
module Example
using CImGui
using CImGui.CSyntax
using CImGui.CSyntax.CStatic
using CImGui.GLFWBackend
using CImGui.OpenGLBackend
using CImGui.GLFWBackend.GLFW
using CImGui.OpenGLBackend.ModernGL
using CImGui.LibCImGui
using Distributed
function ui()
glsl_version = 130
GLFW.WindowHint(GLFW.CONTEXT_VERSION_MAJOR, 3)
GLFW.WindowHint(GLFW.CONTEXT_VERSION_MINOR, 0)
error_callback(err::GLFW.GLFWError) = @error "GLFW ERROR: code $(err.code) msg: $(err.description)"
# setup GLFW error callback
GLFW.SetErrorCallback(error_callback)
# create window
window = GLFW.CreateWindow(1920, 1080, "Example")
@assert window != C_NULL
GLFW.MakeContextCurrent(window)
GLFW.SwapInterval(1) # enable vsync
# setup Dear ImGui context
ctx = CImGui.CreateContext()
# setup Dear ImGui style
CImGui.StyleColorsDark()
# setup Platform/Renderer bindings
ImGui_ImplGlfw_InitForOpenGL(window, true)
ImGui_ImplOpenGL3_Init(glsl_version)
@async try
p_open = true
while !GLFW.WindowShouldClose(window)
GLFW.PollEvents()
ImGui_ImplOpenGL3_NewFrame()
ImGui_ImplGlfw_NewFrame()
CImGui.NewFrame()
p_open && @c showexample(&p_open)
CImGui.Render()
GLFW.MakeContextCurrent(window)
display_w, display_h = GLFW.GetFramebufferSize(window)
glViewport(0, 0, display_w, display_h)
glClearColor(0.2, 0.2, 0.2, 1)
glClear(GL_COLOR_BUFFER_BIT)
ImGui_ImplOpenGL3_RenderDrawData(CImGui.GetDrawData())
GLFW.MakeContextCurrent(window)
GLFW.SwapBuffers(window)
yield()
end
catch e
@error "Error in renderloop!" exception=e
Base.show_backtrace(stderr, catch_backtrace())
finally
ImGui_ImplOpenGL3_Shutdown()
ImGui_ImplGlfw_Shutdown()
CImGui.DestroyContext(ctx)
GLFW.DestroyWindow(window)
end
end
function showexample(p_open::Ref)
CImGui.SetNextWindowPos((600, 100), CImGui.ImGuiCond_Once)
CImGui.SetNextWindowSize((1000, 800), CImGui.ImGuiCond_Once)
if CImGui.Begin("Example", p_open)
CImGui.Button("Add Test") && (add_remote(); add_local())
# CImGui.Button("Add Test") && push!(testlist, Test())
for (i, test) in enumerate(testlist)
CImGui.PushID(i)
edit(test)
CImGui.PopID()
end
CImGui.End()
end
end
mutable struct Test
input1
input2
end
Test() = Test("\0"^16, "\0"^16)
function edit(t::Test)
CImGui.InputTextWithHint("Input1", "Input1", t.input1, length(t.input1)); CImGui.SameLine()
CImGui.InputTextWithHint("Input2", "Input2", t.input2, length(t.input2))
end
testlist = []
function add_remote()
remotecall_wait(workers()[1]) do
push!(testlist, Test())
end
end
function add_local()
testlist_remote = remotecall_fetch(()->testlist, workers()[1]) |> deepcopy
global testlist = testlist_remote
end
end # Example
Example.ui()
Just a little while ago, I found that the problem is the using of deepcopy instead of remote_do.
I'm gonna close this since it looks like the problem is solved.
As the picture shows, when I input 1 in the first InputText Widget, any other Input Widgets will be filled with the same contents, though I have used different IDs. Here is some of the codes: