GLBasic forum

Main forum => GLBasic - en => Topic started by: bigsofty on 2015-Sep-15

Title: PROTOTYPEs, Grrr!
Post by: bigsofty on 2015-Sep-15
I have a small problem with function prototypes. Every time I start to use them it completely breaks my way of coding, I normally do everything in Types, that is, as close as you can get to OO coding in GLB. So if I create a sprite type, I would have a type, with fields, various methods for updating, rendering, creating ect. It usually works great but function prototypes forces you to use static functions, that is create everything outside a type.

So this for example...

Code: (glbasic) [Select]
PROTOTYPE EaseFuncProto#: t#



EaseType[] AS EaseFuncProto


DIM self.EaseType[1]
self.EaseType[0] = self.Linear


Produces this compile error...

Code: (glbasic) [Select]
C:\Users\Ian\AppData\Local\Temp\glbasic\gpc_tempg.cpp: In member function `DGInt __GLBASIC__::TEase::SetUp()':
C:\Users\Ian\AppData\Local\Temp\glbasic\gpc_tempg.cpp:2285: error: no match for 'operator=' in '(((__GLBASIC__::DGArray<__GLBASIC__::EaseFuncProto>*)((__GLBASIC__::TEase*)this)) + 4u)->__GLBASIC__::DGArray<T>::operator() [with T = __GLBASIC__::EaseFuncProto](0) = ((__GLBASIC__::TEase*)this)->__GLBASIC__::TEase::Linear'
C:/Program Files (x86)/GLBasic_v12/Compiler/platform/Include/glb.h:1530: note: candidates are: prototype __GLBASIC__::GLB_PROTO<prototype>::operator=(prototype) [with prototype = DGInt (*)(DGInt)]
C:/Program Files (x86)/GLBasic_v12/Compiler/platform/Include/glb.h:1527: note:                 __GLBASIC__::GLB_PROTO<DGInt (*)(DGInt)>& __GLBASIC__::GLB_PROTO<DGInt (*)(DGInt)>::operator=(const __GLBASIC__::GLB_PROTO<DGInt (*)(DGInt)>&)
*** FATAL ERROR - Please post this output in the forum

I can fix this by basically moving everything out of the type but boy is this messy. I don't see why it needs to be done at compile time as the function pointers can be assigned after a class has been created.

Any suggestion on how to keep PROTOTYPE functionality within the type?
Title: Re: PROTOTYPEs, Grrr!
Post by: Slydog on 2015-Sep-15
I had to check how I did my Easing Library - darn, no TYPE.
I just used simple constants to define the various eases available, such as:

Code: (glbasic) [Select]

Then a quick looked to get the desired value:
Code: (glbasic) [Select]
FUNCTION Tween_Get: transition_type%, p1, p2, time
SELECT transition_type
CASE TWEEN_TYPE_LINEAR; p = TweenTransition_Linear(p1, p2, time)
CASE TWEEN_TYPE_QUAD_IN; p = TweenTransition_QuadIn(p1, p2, time)
CASE TWEEN_TYPE_CUBIC_IN; p = TweenTransition_CubicIn(p1, p2, time)

Why is your EaseType[] an array?  Just curious. Wouldn't an instance of TEase be set to one specific Ease curve?
Wonder if it would work without an array.
Or, try removing the 'self.' portions, so it would be: EaseType[0] = Linear.
(In case the 'self' is throwing it off, although it may not like it.)

I've used PROTOTYPEs in a few places, mainly for callback events on my GUI (button.OnClick(), etc).
Title: Re: PROTOTYPEs, Grrr!
Post by: Slydog on 2015-Sep-15
Here's where I used PROTOTYPEs for my Gui - buttons specifically:

Code: (glbasic) [Select]
@PROTOTYPE PGui_Button_Click: id%

TYPE TGui_Button
xy[] AS TXyXy
fn_click AS PGui_Button_Click

@FUNCTION Set%: caption$, x%, y%, w%, fn_click AS PGui_Button_Click
// Removed other code for readability
self.fn_click = fn_click

This appears close to what your code is doing - I'm setting the prototype inside my TYPE.
One difference is I don't use an array (ha, don't think this is the problem), and the function that is passed is external to the TYPE.  You may have to have a separate TYPE for setting up your Eases, and one TYPE for implementing the Ease?  Just a thought.

[Edit] Not sure what the '@' symbols are for, been a long time.  It may just be to hide something from the navigation / jump panel to the right in the IDE.
Title: Re: PROTOTYPEs, Grrr!
Post by: bigsofty on 2015-Sep-15
Hi Slydog,

Well the function pointer array is just a quicker way of selecting an ease via an indexed array. Its a little micro optimisation on using SELECT/CASE. I've used it to a certain extent in a recent easing library I posted earlier (see... ).

Your Type example is not quite the solution though, as you still can't set the function pointer to a function that resides within the type, "fn_click" must be a static function outside of a type somewhere within your program. You would still need "self." for a function (keep thinking 'method' each time I type this! :P) that is within the GLB type.

The C++ error kinda tells me what the problem is, that is that GLB prototyping is restricted to static functions. I was hoping that someone had found a way around this. I have considered doing the the declaration of the function pointer as inline C++ but I could not get the re-casting to work properly.

BTW I think your right, "@" used to hide a function from the Jump List.
Title: Re: PROTOTYPEs, Grrr!
Post by: Kitty Hello on 2015-Sep-15
Pointer to member functions is not possible.
Title: Re: PROTOTYPEs, Grrr!
Post by: bigsofty on 2015-Sep-16
Lol, OK Gernot, that's kinda to the point.  :D

Do you think that this would be a possible addition at some point?
Title: Re: PROTOTYPEs, Grrr!
Post by: Kitty Hello on 2015-Sep-16
No. C++ does not allow it. I mean if they were static (no ) it would, but that would make GLB more complicated. I'd just use a function and start the name with the TYPE name...
Title: Re: PROTOTYPEs, Grrr!
Post by: bigsofty on 2015-Sep-16
Ah, oh well I can at least put this to bed, its something I've been coming back to many times thinking that I was not seeing the correct way to get it working.