AllenDang / cimgui-go

Auto generated Go wrapper for Dear ImGui via cimgui
MIT License
298 stars 43 forks source link

help creating an example with drag and drop #247

Closed kkevinchou closed 4 months ago

kkevinchou commented 4 months ago

hello, I've been stuck trying to get drag and drop working. If anyone could provide a small working example that'd be greatly appreciated

I've been messing around with various forms of:

    imgui.Button("source button")
    if imgui.BeginDragDropSource() {
        s := "hello"
        p := unsafe.Pointer(&s)
        pp := uintptr(p)
        imgui.SetDragDropPayload("content_browser_item", pp, uint64(len(s)))
        imgui.EndDragDropSource()
    }
    imgui.Button("target button")
    if imgui.BeginDragDropTarget() {
        if payload := imgui.AcceptDragDropPayload("content_browser_item"); payload != nil {
            fmt.Println(payload.Data())
        }
        imgui.EndDragDropTarget()
    }

my goal is to be able to read out the "hello" string on the receiving end, but it causes a crash like this (i added the above example code to the example in this project)

Exception 0xc0000005 0x0 0x0 0x7ff76cf29d80
PC=0x7ff76cf29d80
signal arrived during external code execution

runtime.cgocall(0x7ff76ceff100, 0xc000097b40)
        C:/Program Files/Go/src/runtime/cgocall.go:157 +0x3e fp=0xc000097b18 sp=0xc000097ae0 pc=0x7ff76ce2595e
github.com/AllenDang/cimgui-go._Cfunc_wrap_ImGuiPayload_GetData(0x0)
        _cgo_gotypes.go:52894 +0x52 fp=0xc000097b40 sp=0xc000097b18 pc=0x7ff76ced50f2
github.com/AllenDang/cimgui-go.(*Payload).Data.func2(0x0)
        C:/Users/kkevi/projects/allendang/cimgui-go/cimgui_funcs.go:24083 +0x34 fp=0xc000097b70 sp=0xc000097b40 pc=0x7ff76ced8694
github.com/AllenDang/cimgui-go.(*Payload).Data(0x7ff76d49b137?)
        C:/Users/kkevi/projects/allendang/cimgui-go/cimgui_funcs.go:24083 +0x5d fp=0xc000097bb0 sp=0xc000097b70 pc=0x7ff76ced85fd
main.showWidgetsDemo()
        C:/Users/kkevi/projects/allendang/cimgui-go/examples/main.go:57 +0x1e5 fp=0xc000097c40 sp=0xc000097bb0 pc=0x7ff76cee36a5
main.loop()
        C:/Users/kkevi/projects/allendang/cimgui-go/examples/main.go:120 +0xf fp=0xc000097c50 sp=0xc000097c40 pc=0x7ff76cee3c6f
github.com/AllenDang/cimgui-go.loopCallback()
        C:/Users/kkevi/projects/allendang/cimgui-go/backend.go:29 +0x34 fp=0xc000097c68 sp=0xc000097c50 pc=0x7ff76ced5f94
_cgoexp_db5d66f38144_loopCallback(0x7ff76ce622b1?)
        _cgo_gotypes.go:85029 +0xf fp=0xc000097c78 sp=0xc000097c68 pc=0x7ff76cedaccf
runtime.cgocallbackg1(0x7ff76cedacc0, 0xa1857ff59f, 0x0)
        C:/Program Files/Go/src/runtime/cgocall.go:403 +0x2b1 fp=0xc000097d38 sp=0xc000097c78 pc=0x7ff76ce260b1
runtime.cgocallbackg(0x7ff76cedacc0, 0xa1857ff59f, 0x0)
        C:/Program Files/Go/src/runtime/cgocall.go:322 +0x133 fp=0xc000097db0 sp=0xc000097d38 pc=0x7ff76ce25d53
runtime.cgocallbackg(0x7ff76cedacc0, 0xa1857ff59f, 0x0)
        <autogenerated>:1 +0x2e fp=0xc000097dd8 sp=0xc000097db0 pc=0x7ff76ce88b6e
runtime.cgocallback(0xc000097e38, 0x7ff76ce25992, 0x7ff76cf22510)
        C:/Program Files/Go/src/runtime/asm_amd64.s:1079 +0xec fp=0xc000097e00 sp=0xc000097dd8 pc=0x7ff76ce8406c
runtime.systemstack_switch()
        C:/Program Files/Go/src/runtime/asm_amd64.s:474 +0x8 fp=0xc000097e10 sp=0xc000097e00 pc=0x7ff76ce822a8
runtime.cgocall(0x7ff76cf22510, 0xc000097e70)
        C:/Program Files/Go/src/runtime/cgocall.go:175 +0x72 fp=0xc000097e48 sp=0xc000097e10 pc=0x7ff76ce25992
github.com/AllenDang/cimgui-go._Cfunc_igGLFWRunLoop(0x27b1f33d0a0, 0x7ff76cee41a0, 0x7ff76cee41e0, 0x7ff76cee4220, 0x7ff76cee42a0)
        _cgo_gotypes.go:23601 +0x4d fp=0xc000097e70 sp=0xc000097e48 pc=0x7ff76ced3d2d
github.com/AllenDang/cimgui-go.(*GLFWBackend).Run.func1(0xc00010a010?)
        C:/Users/kkevi/projects/allendang/cimgui-go/glfw_backend.go:249 +0x9c fp=0xc000097ed8 sp=0xc000097e70 pc=0x7ff76ced905c
github.com/AllenDang/cimgui-go.(*GLFWBackend).Run(0xc000084050?, 0xc00010a000?)
        C:/Users/kkevi/projects/allendang/cimgui-go/glfw_backend.go:249 +0x32 fp=0xc000097ef0 sp=0xc000097ed8 pc=0x7ff76ced8f92
main.main()
        C:/Users/kkevi/projects/allendang/cimgui-go/examples/main.go:158 +0x374 fp=0xc000097f50 sp=0xc000097ef0 pc=0x7ff76cee4054
runtime.main()
        C:/Program Files/Go/src/runtime/proc.go:271 +0x28b fp=0xc000097fe0 sp=0xc000097f50 pc=0x7ff76ce58feb
runtime.goexit({})
        C:/Program Files/Go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000097fe8 sp=0xc000097fe0 pc=0x7ff76ce842e1

goroutine 2 gp=0xc000068700 m=nil [force gc (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        C:/Program Files/Go/src/runtime/proc.go:402 +0xce fp=0xc00006bfa8 sp=0xc00006bf88 pc=0x7ff76ce593ee
runtime.goparkunlock(...)
        C:/Program Files/Go/src/runtime/proc.go:408
runtime.forcegchelper()
        C:/Program Files/Go/src/runtime/proc.go:326 +0xb8 fp=0xc00006bfe0 sp=0xc00006bfa8 pc=0x7ff76ce59278
runtime.goexit({})
        C:/Program Files/Go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00006bfe8 sp=0xc00006bfe0 pc=0x7ff76ce842e1
created by runtime.init.6 in goroutine 1
        C:/Program Files/Go/src/runtime/proc.go:314 +0x1a

goroutine 3 gp=0xc000068a80 m=nil [GC sweep wait]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        C:/Program Files/Go/src/runtime/proc.go:402 +0xce fp=0xc00006df80 sp=0xc00006df60 pc=0x7ff76ce593ee
runtime.goparkunlock(...)
        C:/Program Files/Go/src/runtime/proc.go:408
runtime.bgsweep(0xc00001c070)
        C:/Program Files/Go/src/runtime/mgcsweep.go:278 +0x94 fp=0xc00006dfc8 sp=0xc00006df80 pc=0x7ff76ce44034
runtime.gcenable.gowrap1()
        C:/Program Files/Go/src/runtime/mgc.go:203 +0x25 fp=0xc00006dfe0 sp=0xc00006dfc8 pc=0x7ff76ce38b45
runtime.goexit({})
        C:/Program Files/Go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00006dfe8 sp=0xc00006dfe0 pc=0x7ff76ce842e1
created by runtime.gcenable in goroutine 1
        C:/Program Files/Go/src/runtime/mgc.go:203 +0x66

goroutine 4 gp=0xc000068c40 m=nil [GC scavenge wait]:
runtime.gopark(0xc00001c070?, 0x7ff76d4be878?, 0x1?, 0x0?, 0xc000068c40?)
        C:/Program Files/Go/src/runtime/proc.go:402 +0xce fp=0xc00007df78 sp=0xc00007df58 pc=0x7ff76ce593ee
runtime.goparkunlock(...)
        C:/Program Files/Go/src/runtime/proc.go:408
runtime.(*scavengerState).park(0x7ff76d657800)
        C:/Program Files/Go/src/runtime/mgcscavenge.go:425 +0x49 fp=0xc00007dfa8 sp=0xc00007df78 pc=0x7ff76ce41a29
runtime.bgscavenge(0xc00001c070)
        C:/Program Files/Go/src/runtime/mgcscavenge.go:653 +0x3c fp=0xc00007dfc8 sp=0xc00007dfa8 pc=0x7ff76ce41fbc
runtime.gcenable.gowrap2()
        C:/Program Files/Go/src/runtime/mgc.go:204 +0x25 fp=0xc00007dfe0 sp=0xc00007dfc8 pc=0x7ff76ce38ae5
runtime.goexit({})
        C:/Program Files/Go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00007dfe8 sp=0xc00007dfe0 pc=0x7ff76ce842e1
created by runtime.gcenable in goroutine 1
        C:/Program Files/Go/src/runtime/mgc.go:204 +0xa5

goroutine 5 gp=0xc000069180 m=nil [finalizer wait]:
runtime.gopark(0xc00006fe48?, 0x7ff76ce2f0e5?, 0xa8?, 0x1?, 0xc000068000?)
        C:/Program Files/Go/src/runtime/proc.go:402 +0xce fp=0xc00006fe20 sp=0xc00006fe00 pc=0x7ff76ce593ee
runtime.runfinq()
        C:/Program Files/Go/src/runtime/mfinal.go:194 +0x107 fp=0xc00006ffe0 sp=0xc00006fe20 pc=0x7ff76ce37bc7
runtime.goexit({})
        C:/Program Files/Go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00006ffe8 sp=0xc00006ffe0 pc=0x7ff76ce842e1
created by runtime.createfing in goroutine 1
        C:/Program Files/Go/src/runtime/mfinal.go:164 +0x3d
rax     0xc000098000
rbx     0xc000097b40
rcx     0x0
rdx     0xc000097ad0
rdi     0xc000098000
rsi     0x7ff76d6578a0
rbp     0xa1857ff410
rsp     0xa1857ff3a8
r8      0x7ff76d657e60
r9      0x0
r10     0x3
r11     0xa1857ff350
r12     0xc00010d760
r13     0x0
r14     0xc000068000
r15     0x7ffff
rip     0x7ff76cf29d80
rflags  0x10202
cs      0x33
fs      0x53
gs      0x2b
exit status 2
gucio321 commented 4 months ago

@kkevinchou your nil check is wrong. payload != nil checks if go wrapper is nil, but the actual thing you want not t be nil is payload.CData. I'm sorry tha it is this way but thats because of GO. its like this:

type Payload struct {
        CData *C.ImGuiPayload
}

because if it was simply type Payload *C.ImGuiPayload go complains that "invalid receiver type foo (pointer or interface type)"

I hope this helped ;-)

kkevinchou commented 4 months ago

thanks! that clarifies things. how would I be able to extract the actual "hello" text in my example? i've tried to cast the unsafe.Pointer into a (*string) but I'm getting an empty string back:

fmt.Println(*(*string)(payload.CData.Data))
gucio321 commented 4 months ago

@kkevinchou Your method of converting uintptr to string pointer is right. Whats wrong in your code is the sz arg in SetDragDropPayload. This should be a memory size of your string, not its len, so len(s)* sizeof(rune). Go has a nice way to calculate this: unsafe.Sizeof(s) will work.

kkevinchou commented 4 months ago

that was my issue, thanks for the help!