How to init a func pointer array?

BlitzMax Forums/BlitzMax Programming/How to init a func pointer array?

BladeRunner(Posted 2009) [#1]

type test
    field funcarray:int(data:object,stuff:int)[]
...

    function create:test(size:int)
        local t:test = new test
        t.funcarray = new ???[size]
        ....

The problem is where the ??? are. Any clue how to init the array of function pointers?
All my tries ended with 'expecting [' or 'cannot change xxx array to yyy array' errors.


BladeRunner(Posted 2009) [#2]
forget about it, I got it:
t.funcarry =t.funcarray[..size]

Wondering if you have to go by 'slicing' the array or if there are other ways with init by new.


ImaginaryHuman(Posted 2009) [#3]
I think either you have to specify the size at the time of creating the array itself, or slice it later. You can't later on create a new `test` type and expect it to somehow resize the array because the array and the type are not connected. So either:

Field funcarray:int(data:object,stuff:int)[100]

or like you did above.


BladeRunner(Posted 2009) [#4]
I was runing into this problem beause you actually can init the array with new as long as it isn't a function pointer array.
If it was an Int-Array I just could have used
t.array = new int[100] - which is what I consider a clean way of init.
So I think this could be understood as somewhat buggy behaviour of BMax.
But as long as it runs I don't care ;)


ImaginaryHuman(Posted 2009) [#5]
Why can't you do t.array=new myfunction[100]?


Warpy(Posted 2009) [#6]
Because it's not an array of the same function 100 times, it's an array of 100 arbitrary functions.
What it comes down to is that blitz wasn't designed for _everything_ to be an object, but can still do stuff like function pointers, so there isn't a keyword for the function pointer 'type'.


ImaginaryHuman(Posted 2009) [#7]
Oh I see, so you have functions with many different numbers of parameters and of different types - yeah, you can only store one `template` of a function in an array. I had the same problem myself when I wanted to store many different function definitions in an array. Couldn't do it. I had to make all of the functions generic - ie have say 5 integer parameters on every function, even if I don't use them all. Another way is to not pass any parameters at all. Instead, pass a pointer to some area of memory where store parameters in an integer array, plus a parameter saying how many parameters to read perhaps - unless you hardcode it. Then the function reads n elements from the parameter memory and converts them as needed into other types by casting them. Not exactly elegant but it works.


Warpy(Posted 2009) [#8]
I feel dirty:

Global arg_ints[]
Global arg_floats#[]
Global arg_objects:Object[]
Global res_ints[]
Global res_floats#[]
Global res_objects:Object[]

Function fi()(ints[],func())
	arg_ints=ints
	res_ints=New Int[0]
	res_floats=New Float[0]
	res_objects=New Object[0]
	Return func
End Function

Function ff()(floats#[],func())
	arg_floats=floats
	res_ints=New Int[0]
	res_floats=New Float[0]
	res_objects=New Object[0]
	Return func
End Function

Function fo()(objects:Object[],func())
	arg_objects=objects
	res_ints=New Int[0]
	res_floats=New Float[0]
	res_objects=New Object[0]
	Return func
End Function



'example

Function middles()
	'takes 2 ints - startchar and endchar
	'takes an array of strings
	'returns the middle bits of the strings, between startchar and endchar

	startchar = arg_ints[0]
	endchar = arg_ints[1]
	
	For s$=EachIn arg_objects
		res_objects:+[s[startchar..endchar]]
	Next
End Function


fi([2,7],fo(["rrhellorrr","rrthererrrr"],middles))()

For s$=EachIn res_objects
	Print s
Next



What this does is abuse a few global arrays and some function pointers. Each of the functions fi,ff,fo take an array of arguments of type int, float or object, respectively, and a function pointer. They save the array of arguments in the global, and return the function pointer.

This way, you can 'pile up' the calls to these functions, using the result from fo as the function parameter for fi, like in the example, allowing you to call the function in one line, with no repetition, and only some hideous punctuation in the middle.

I don't think anyone should use this, it's a gruesome bending of the rules, but you never know!


ImaginaryHuman(Posted 2009) [#9]
Interesting. :)