Function storage

BlitzMax Forums/BlitzMax Programming/Function storage

col(Posted 2011) [#1]
Hi all

Is there a way to store a collection of function pointers in say an array or list or similar so that i can still call the function later ?

for eg..

Can i have an array of 10 functions or pointers, so if i call array[4] it will call the function?

The function parameters will be the same across the whole 'collection'.

Many thanks


GW(Posted 2011) [#2]
Did you even try it?


kfprimm(Posted 2011) [#3]
Something like,



col(Posted 2011) [#4]
thanks kfprimm,

I was using

SuperStrict

Local l:Byte Ptr[5]

l[0]=test1
l[1]=test2

l[0]

Function test1()
	Print"1"
EndFunction

Function test2()
	Print"2"
EndFunction


I wasn't sure how to get it back to a function, lol. 3am is definately not the best time to code :-)

Cheers


col(Posted 2011) [#5]
@GW
My next question was going to be 'Can you write my AAA FPS #1 for 2 years in the charts blockbuster game for me?' :o)

But I think I'll pass on that one.


ImaginaryHuman(Posted 2011) [#6]
One thing I did a while ago which I thought was very clever at the time, was to basically store a big long list of function pointers in an array and treat it like a `program` for a script language. Execution of the script simply entails moving through the array and calling each function. Of course every function then has to have the same number and type of parameters, so I simply passed a pointer or something to some storage memory where I kept variables and then each function would pull up as many as it needs. I would let each function modify a `program counter` ie the index in the array, to implement loops and jumps etc. I even implemented some multitasking and task scheduling and it actually performed quite well. But this was just before Blitz gained true multithreading capability so that kind of rendered it obsolete. But using an array of function pointers as a `program` is still pretty cool.

Last edited 2011


col(Posted 2011) [#7]
Hi Imaginary Human

That is clever and sounds like a great way to code a script language. Maybe an emulator? Just curious of course :p

I wrote a Z80 emulator last year and had the Pacman ROMs working through it. It's a great achievement to actually program a CPU, and I loved every minute of it. It took about 2 weeks to get everything ironed out, but thoroughly enjoyable.
I remember I initially did what I was trying to do last night ( I had a brain - fart last night because of burning the candle at both ends!! ) , in that I had an array of function pointers one for each OpCode, my thinking was a single function call to get to the opcode to run, but varying parameters put me off going any further investigation down that route as a simple Select - Case structure was so much easier to program and debug. It runs respectably well on my laptop for an emulator in a 'Basic' language. Achieving well over 120 FPS without VSync. Theres much more room for optimization too but i didn't bother any further. The point of the exercise was that it worked :-)

Nice work.


Czar Flavius(Posted 2011) [#8]
You could also create a TFunctiod type with an abstract DoSomething method, and extend various types from it that do something different for each version of the method. Then you create an array of TFunctiod but populate it with New TFHelloWorld and New TFCoolStuff as required. Just an alternative.


col(Posted 2011) [#9]
Thats a good idea there. One day I may take a look at the emulator again and convert it to my original idea with your idea in there too. I'd give credit to you for your idea.


Kryzon(Posted 2011) [#10]
Why are you using a Byte value to hold the function pointer? shouldn't it be an integer?


ImaginaryHuman(Posted 2011) [#11]
lol yeah, running through an array of function pointers is actually very fast. Or pretty good, anyway. I think it could do hundreds of thousands of function calls/second. I was developing a script language similar in simplicity to assembler where you just have simple commands to do simple tasks, although they were going to do quite high-level tasks. And then every so often I'd check a timer or something to see if it was time to switch tasks and then would jump to calling functions in a different array. I even made the task scheduler somewhat inspired by the one in the Linux kernel. But then like I said Mark implemented proper threads finally so it sort of made it a bit obsolete, although the idea of doing a simple script language with function pointer programs is quite handy and easy to do.

On a totally different topic, why do people insist on putting a `T` in the name of every custom type? We KNOW it's a type, every single one shouldn't need a T. lol


Czar Flavius(Posted 2011) [#12]
Local apple:TApple

In C++ there is a convention where the type name has a capital letter, so
Apple apple;

But BM isn't case-sensitive, plus I don't think that is a good thing to rely on anyway.

I guess it's redundant, but I'm used to it now.


col(Posted 2011) [#13]
@Imaginary Human
Very clever idea:-)

Like Czar Flavius says, its just a convention.

For me, when doing larger projects it can make code so much easier to read with some kind of convention. The initial of the datatype is the first letter of the variable.
I regular, but no always, use the following :-
g_pName for a global type or ptr
m_iName for a field member of a type thats an Integer
m_fFloat for a float.

I believe this is similar to a technique called 'Hungarian Notation'??

You get the idea. Theres nothing worse that looking through 5000 lines of code and having to keep skipping to the definitions to check the datatype.

@Kryzon
Byte Ptr can be thought of as a kind of 'generic pointer'. Its still just a 32 bit memory address. Try changing it to Int Ptr and you will see it won't compile.

Last edited 2011


Kryzon(Posted 2011) [#14]
I understand it now. Thanks for the info col =)