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

Support *Scalar functions #74

Open
ptxmac opened this issue Dec 31, 2022 · 11 comments
Open

Support *Scalar functions #74

ptxmac opened this issue Dec 31, 2022 · 11 comments
Labels
enhancement New feature or request

Comments

@ptxmac
Copy link
Contributor

ptxmac commented Dec 31, 2022

I was looking for a DragDouble widget, but imgui has been implementing new datatypes using the *Scalar widgets instead.

These work just like DragInt/Float/Etc but takes an enum declaring the type and a void pointer to the data.

For this to work from go we need a way to manually wrap the go pointer, i.e. make wrapNumberPtr public.

Or perhaps implement DragScalar with a switch that will type-cast based on the DataType.

something like:

func DragScalar(label string, data_type DataType, p_data unsafe.Pointer) bool {
	labelArg, labelFin := wrapString(label)
	defer labelFin()

        switch (data_type) {
        case DataType_Double:
             	vArg, vFin = wrapNumberPtr[C.double, float64](v)
        } 

      	defer vFin()

	return C.DragScalar(labelArg, C.ImGuiDataType(data_type), vArg) == C.bool(true)
}
@AllenDang
Copy link
Owner

I'd say this is not necessary. We could easily create a one based on basic drag int or float.

@AllenDang
Copy link
Owner

Mess with pointer data via CGO is not that pleasant after all.

@ptxmac
Copy link
Contributor Author

ptxmac commented Dec 31, 2022

Mess with pointer data via CGO is not that pleasant after all.

agreed, but for certain applications the loss of precision when converting between float and double is unacceptable.

we could create DragDouble instead of switching in DragScalar, but then we should probably also create the rest of the supported datatypes: signed and unsigned 8/16/32/ 64 bit integers

@gucio321
Copy link
Collaborator

@AllenDang I think we can make our wrappers public to make *Scalar functions easier to use

@gucio321 gucio321 added the enhancement New feature or request label Apr 20, 2023
@gucio321
Copy link
Collaborator

gucio321 commented Sep 6, 2023

@ptxmac from current code:

// InputScalarV parameter default value hint:
// p_step: NULL
// p_step_fast: NULL
// format: NULL
// flags: 0
func InputScalarV(label string, data_type DataType, p_data unsafe.Pointer, p_step unsafe.Pointer, p_step_fast unsafe.Pointer, format string, flags InputTextFl
        labelArg, labelFin := WrapString(label)
        formatArg, formatFin := WrapString(format)

        defer func() {
                labelFin()
                formatFin()
        }()
        return C.igInputScalar(labelArg, C.ImGuiDataType(data_type), (p_data), (p_step), (p_step_fast), formatArg, C.ImGuiInputTextFlags(flags)) == C.bool(tru
}

So I suppose its fixed

@gucio321 gucio321 closed this as completed Sep 6, 2023
@ptxmac
Copy link
Contributor Author

ptxmac commented Oct 5, 2024

It looks like this has been broken again, now the code is uintptr instead of a real pointer

@gucio321
Copy link
Collaborator

gucio321 commented Oct 5, 2024

@ptxmac what's wrong with it?

@ptxmac
Copy link
Contributor Author

ptxmac commented Oct 5, 2024

The code gen doesn't see the value as a pointer, so it's never copied.

Current code:

func InputScalar(label string, data_type DataType, p_data uintptr) bool {
	labelArg, labelFin := datautils.WrapString[C.char](label)

	defer func() {
		labelFin()
	}()
	return C.wrap_igInputScalar(labelArg, C.ImGuiDataType(data_type), C.uintptr_t(p_data)) == C.bool(true)
}

It should be similar to InputInt:

func InputInt(label string, v *int32) bool {
	labelArg, labelFin := datautils.WrapString[C.char](label)
	vArg, vFin := datautils.WrapNumberPtr[C.int, int32](v)

	defer func() {
		labelFin()
		vFin()
	}()
	return C.wrap_igInputInt(labelArg, vArg) == C.bool(true)
}

But where the type of v depends on the data_type argument.

@ptxmac
Copy link
Contributor Author

ptxmac commented Oct 5, 2024

Basically the fix mentioned in #74 (comment) have regressed and we're back to the original problem

@gucio321 gucio321 reopened this Oct 5, 2024
@gucio321
Copy link
Collaborator

gucio321 commented Oct 5, 2024

yeah. I think there were a problem with -race maybe... let me reopen that and thats all I can do for now (i'm working on my other project atm)

@ptxmac
Copy link
Contributor Author

ptxmac commented Oct 12, 2024

I had another look, and it actually is possible to use using the current implementation. IT's just not very ergonomic 😄

func Scalar(v *int32) {
	vArg, vFin := datautils.WrapNumberPtr[C.int, int32](v)
	defer vFin()

	imgui.InputScalar("Scalar", imgui.DataTypeS32, uintptr(unsafe.Pointer(vArg)))
}

func ScalarN(v *[3]int32) {
	vArg := make([]C.int, len(v))
	for i, val := range v {
		vArg[i] = C.int(val)
	}

	defer func() {
		for i, val := range vArg {
			v[i] = int32(val)
		}
	}()

	imgui.InputScalarN("ScalarN", imgui.DataTypeS32, uintptr(unsafe.Pointer(&vArg[0])), 3)
}

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

No branches or pull requests

3 participants