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

Allow for specification overloads #107

Merged
merged 15 commits into from
Jun 3, 2020
Merged

Allow for specification overloads #107

merged 15 commits into from
Jun 3, 2020

Conversation

dertseha
Copy link
Contributor

@dertseha dertseha commented May 23, 2020

This pull request is a proposal for the solution of current problems with checkptr and the unsafe.Pointer / uintptr converions. There are several issues across several projects already - I suppose go-gl/gl#80 is the most central one.

With this code change, it is possible to have (manually written) XML files under <xmlDir>/overload with same name as the main spec files. So, for xml/spec/gl.xml the file xml/overload/gl.xml would be matched.

I included a sample overload file, to showcase how this is to be used:

  • For gl.VertexAttribPointer(..., unsafe.Pointer) it creates a gl.VertexAttribOffset(..., uintptr) overload
  • For gl.GetVertexAttribPointerv(..., *unsafe.Pointer) it creates a gl.GetVertexAttribOffsetv(..., **uintptr) overload
  • For gl.DrawElements(..., unsafe.Pointer) it creates a gl.DrawElementsWithOffset(..., uintptr) overload

The created code looks like this - example for VertexAttribPointer:

...
// static void  glowVertexAttribPointer(GPVERTEXATTRIBPOINTER fnptr, GLuint  index, GLint  size, GLenum  type, GLboolean  normalized, GLsizei  stride, const void * pointer) {
//   (*fnptr)(index, size, type, normalized, stride, pointer);
// }
// static void  glowVertexAttribOffset(GPVERTEXATTRIBPOINTER fnptr, GLuint  index, GLint  size, GLenum  type, GLboolean  normalized, GLsizei  stride, uintptr_t  offset) {
//   (*fnptr)(index, size, type, normalized, stride, (const void *)(offset));
// }
...
func VertexAttribPointer(index uint32, size int32, xtype uint32, normalized bool, stride int32, pointer unsafe.Pointer) {
	C.glowVertexAttribPointer(gpVertexAttribPointer, (C.GLuint)(index), (C.GLint)(size), (C.GLenum)(xtype), (C.GLboolean)(boolToInt(normalized)), (C.GLsizei)(stride), pointer)
}
func VertexAttribOffset(index uint32, size int32, xtype uint32, normalized bool, stride int32, offset uintptr) {
	C.glowVertexAttribOffset(gpVertexAttribPointer, (C.GLuint)(index), (C.GLint)(size), (C.GLenum)(xtype), (C.GLboolean)(boolToInt(normalized)), (C.GLsizei)(stride), (C.uintptr_t)(offset))
}
...

I wanted to stay clear of the core specification files, which is why a separate set of files is used.
I also don't know of all the affected cases. My guess (hope) would be, that, once accepted, people provide corresponding overloads via dedicated pull requests. Perhaps it's also a small subset of affected functions. Return types are not handled (are there cases?)

Also not clear is the naming. Should all the overloads have a suffix WithOffset? In the special case of VertexAttribPointer for instance, the WebGL variant even calls it VertexAttribIPointer (Note the extra I - also, their overload has one parameter less, something that could also be replicated...)

For all these uncertainties, I propose to continue the discussion in go-gl/gl#80 .

@errcw
Copy link
Member

errcw commented May 27, 2020

Thanks Christian, this is great. Apologies for not having the opportunity to review this sooner. I agree that offering explicit overrides/extensions is the right approach to manage the fact that a single OpenGL function has two effectively different signatures.

One thought: As an alternative to explicit overrides, what if we offered an additional XML file that introduced a new namespace, so we'd have something like gogl.VertexAttribOffset. That would allow for reusing more of the existing "infrastructure" in glow while keeping the same basic idea intact?

@dertseha
Copy link
Contributor Author

Thank you for the reply.
As for a new namespace: The tricky part is that the overload function wants to call the original with a different type of argument and requires explicit casting. So, at least the types would require additional information, and I wanted to avoid touching the "official" spec schema.
Furthermore, as also pointed out in go-gl/gl#80 , with fixed suffixes people see in their IDE all variants to pop up and (possibly) make people think. If the functions are "hidden" in another package, this might get overlooked more easily.
The way it is implemented now, it already re-uses existing infrastructure: The original function must be present (errors if it doesn't) and the original type information is used to create the necessary casts.

(I still need to update this PR with the proper suffix for the one example.)

Also, you use the term "override" while I took "overload". I specifically chose "overload" as the new function does not hide the original and at least one parameter is different - two properties that "overriding" does not have.
By pointing this out I want to avoid the subtle assumption by later developers that there's no difference.

@errcw
Copy link
Member

errcw commented May 29, 2020

Makes sense, thanks for the explanation. Your change largely LGTM but I have a few nits.

overload.go Outdated Show resolved Hide resolved
overload.go Outdated Show resolved Hide resolved
spec.go Outdated Show resolved Hide resolved
// An Overload describes an alternative signature for the same function.
type Overload struct {
Name string // C name of the original function
GoName string // Go name of the original function
Copy link
Member

Choose a reason for hiding this comment

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

could this value be pulled from the parent struct? similarly for Name?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Name turned out not to be necessary. As for GoName, I was not able to figure out an easy way to access GoName from the parent from the sub-template overloadCall. Hence I kept this field

@dertseha
Copy link
Contributor Author

Comments handled.
I've also extended README.md to hint at the overload functionality.

README.md Outdated Show resolved Hide resolved
@errcw
Copy link
Member

errcw commented Jun 3, 2020

Thank, this looks great. I have one very tiny documentation change to request, and otherwise I'm happy to merge!

@errcw errcw merged commit 76a5465 into go-gl:master Jun 3, 2020
@errcw
Copy link
Member

errcw commented Jun 3, 2020

Thanks again!

@dertseha
Copy link
Contributor Author

dertseha commented Jun 3, 2020

Sure thing - thank you!
The actual work now starts to figure out which functions are affected and add overloads.

@dertseha dertseha deleted the feature/with-offset-overloads branch June 3, 2020 17:18
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.

2 participants