View Full Version : how to call a user script function from TB_Module?
D.J.Peters
17-03-2010, 22:14
How can I trigger an event or call a user defined script function from TB_Module ?
use FreeSound
hStream = CreateNewMP3Stream(NewFile))
MP3StreamSetEndCallback(hStream, "MyCallBack")
StartMP3Stream(hStream)
' ...
sub MyCallBack(StreamID)
printl "end of MP3 stream !" + str$(StreamID)
end sub
thank you
Joshy
Petr Schreiber
17-03-2010, 22:22
Hi Joshy,
you can retrieve "pointer" to thinBASIC function using:
fPTR = thinBasic_FunctionParseAndGetPtr(%FALSE)
and then execute it using:
thinBasic_FunctionSimpleCall_ByPtr(fPTR)
Please note the pointer is not true code pointer, due to thinBasic interpreted nature.
Eros will know more.
Petr
ErosOlmi
20-03-2010, 12:07
Sorry to be so late in replying but currently I'm having heavy load at work.
Petr already replied correctly.
Use "fPTR = thinBasic_FunctionParseAndGetPtr(%FALSE)" to parse the name of the function indicated in script and get its thinBasic internal pointer.
In your code, when you need to call that script function use "thinBasic_FunctionSimpleCall_ByPtr(fPTR)"
If you need more info let me know.
Eros
D.J.Peters
20-03-2010, 13:16
Thank you both
i got callbacks with params working
(after i created a new and complete import lib from thinCore.dll)
Joshy
Uses "FGLUT"
' multiply windows with callbacks
CallBack Sub Reshape(ByVal WinID As Long, _
ByVal W As Long, _
ByVal H As Long)
Local Ratio As Single
If H = 0 Or W = 0 Then Exit Sub
If W>H Then
Ratio=W/H
Else
Ratio=H/W
End If
glViewport(0,0,w,h)
glMatrixMode(%GL_PROJECTION)
glLoadIdentity()
gluPerspective(90.0, Ratio, 1.0, 100.0)
glMatrixMode(%GL_MODELVIEW)
If WinID=1 Then
glClearColor(0.8,0.2,0.2,1)
glColor3f(0.2,0.5,0.5)
ElseIf WinID=2 Then
glClearColor(0.2,0.8,0.2,1)
glColor3f(0.5,0.2,0.5)
Else
glClearColor(0.2,0.2,0.8,1)
glColor3f(0.5,0.5,0.2)
End If
End Sub
CallBack Sub Display(ByVal WinID As Long)
glClear(%GL_COLOR_BUFFER_BIT Or %GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
gluLookAt(0.0, 1.0, 6.0, _ ' from
0.0, 0.0, 0.0, _ ' to
0.0, 1.0, 0.0) ' up vector
Select Case WinID
Case 1:FGLUT_WireTeapot(4)
Case 2:FGLUT_WireSphere(4)
Case 3:FGLUT_SolidTeapot(4)
End Select
FGLUT_SwapBuffers
End Sub
CallBack Sub Keyboard(ByVal WinID As Long, _
ByVal Key As Long, _
ByVal X As Long, _
ByVal Y As Long)
If Key=27 Then FGLUT_DestroyWindow(WinID)
End Sub
Dim i,WinIDs(3) As Long
' create 3 windows
WinIDs(1)=FGLUT_NewWindowEx( 0, 0,400,400,"window 1")
WinIDs(2)=FGLUT_NewWindowEx(410, 0,400,400,"window 2")
WinIDs(3)=FGLUT_NewWindowEx( 0,438,810,200,"window 3")
' set for all windows callback's
For i=1 To 3
FGLUT_SetWindow(WinIDs(i))
FGLUT_SetDisplayCallback(Display)
FGLUT_SetKeyboardCallback(Keyboard)
FGLUT_SetReshapeCallback(Reshape)
Next
' start your engines ;-)
FGLUT_MainLoop
Charles Pegge
20-03-2010, 16:16
Hi Joshy,
I am conferring with Eros to bring the FreeBasic / thinCore SDK up to version 1.8.00. We have not given it any attention since August 2008 and much has been added since then. If all is well then it can be released with the next thinBasic beta.
Strings (BSTR) and Extended Floats of course require special attention in FreeBasic modules, but I am not tempted to create a full set of wrapper functions since most TB modules only require a small number of conversions.
Charles
D.J.Peters
20-03-2010, 21:48
hello Charles
if assembler is your primary language then all other are not realy a problem.
(i used C++ classes in VB6 or FreeBASIC in the past)
With an uptodate def file you can create for any language a import lib.
BSTR is simple an pointer on OLECHAR an FreeBASIC coder can use simple macros
dim shared as EXT ext_null
dim shared as EXT ext_value
dim shared as BSTR bstr_name
dim shared as BSTR bstr_value
' register string const
#macro RSC(name,value)
bstr_name = SysAllocStringByteLen(name,len(name))
bstr_value = SysAllocStringByteLen(value,len(value))
thinBasic_AddEquate bstr_name,bstr_value,ext_null,0
SysFreeString bstr_name
SysFreeString bstr_value
#endmacro
' register long const
#macro RLC(name,value)
Long2Ext(@ext_value,value)
bstr_name = SysAllocStringByteLen(name,len(name))
bstr_value = 0
thinBasic_AddEquate bstr_name,bstr_value,ext_value,0
SysFreeString bstr_name
#endmacro
The biggest problem for FB user is
the EXT 'ended data type has a wrong declaration in the thinCore.bi file
is must be
type EXT field=1
dbl as double
xtn as word
end typewith the wrong declare you can't link to the import lib
of course EXT is 10 bytes (fldt fstpt) and not 12 bytes.
But i know you're also a hardcore coder ;)
happy coding
Joshy
Charles Pegge
21-03-2010, 02:14
Hi Joshy,
Yes I agree. With Asm handling Ext in Freebasic is easy. But to make all the thinCore functions work transparently in all cases we may be compelled to provide wrapper functions and work in Doubles. I cannot see how we can avoid this for FreeBasic (0.20) unfortunately. Ext numbers cannot be perfectly emulated in a freebasic expression.
When Ext numbers are passed byval on the stack, the alignment is 12 bytes but within a PB / TB array they are packed to 10 bytes as you indicate, so I will change this.
Thanks.
Charles.
D.J.Peters
21-03-2010, 05:44
I cannot see how we can avoid this for FreeBasic (0.20) unfortunately. Ext numbers cannot be perfectly emulated in a freebasic expression.
you can create any new data type in FreeBASIC
and overload missing operators like SQR,^,Mod ...
or i don't understand your message :oops:
Joshy
type FLOAT80
as byte bytes(9) ' 0-9 = 10 bytes
end type
type EXT
as FLOAT80 Value
declare constructor
declare constructor(byref l as EXT)
declare constructor(byval l as double)
declare operator cast as string
end type
constructor EXT
' dummy constructor
end constructor
constructor EXT(byref l as EXT)
dim as any ptr d =@value,s=@l.value
asm
mov eax,[s]
fldt [eax]
mov eax,[d]
fstpt [eax]
end asm
end constructor
constructor EXT(byval l as double)
dim as any ptr p =@value
asm
fld qword ptr [l]
mov eax,[p]
fstpt [eax]
end asm
end constructor
operator EXT.cast as string
dim as any ptr p = @value
dim as double d = any
asm
mov eax,[p]
fldt [eax]
fstp qword ptr [d]
end asm
return str(d)
end operator
Operator + (ByRef l As EXT, ByRef r As EXT) As EXT
dim as EXT t
dim as any ptr p = @t.value
asm
mov eax,[l]
fldt [eax]
mov eax,[r]
fldt [eax]
faddp
mov eax,[p]
fstpt [eax]
end asm
Return t
End Operator
Operator - (ByRef l As EXT, ByRef r As EXT) As EXT
dim as EXT t
dim as any ptr p = @t.value
asm
mov eax,[l]
fldt [eax]
mov eax,[r]
fldt [eax]
fsubp
mov eax,[p]
fstpt [eax]
end asm
Return t
End Operator
Operator / (ByRef l As EXT, ByRef r As EXT) As EXT
dim as EXT t
dim as any ptr p = @t.value
asm
mov eax,[l]
fldt [eax]
mov eax,[r]
fldt [eax]
fdivp
mov eax,[p]
fstpt [eax]
end asm
Return t
End Operator
Operator * (ByRef l As EXT, ByRef r As EXT) As EXT
dim as EXT t
dim as any ptr p = @t.value
asm
mov eax,[l]
fldt [eax]
mov eax,[r]
fldt [eax]
fmulp
mov eax,[p]
fstpt [eax]
end asm
Return t
End Operator
dim as EXT a = 1.0
dim as EXT b = 3.0
dim as EXT c = a+b*2
dim as EXT d = a/b
print a,b,c,d
sleep
Charles Pegge
21-03-2010, 07:52
Wow! this is new to me. I have some catching up to do!
Thanks Joshy.
Charles
D.J.Peters
21-03-2010, 21:58
finaly you can create a libext.a and link it to gether with libthinCore.dll.a
and the result could be libthinCoreFB.dll.a
or you put in thinCore.bi #include "ext.bi" witch used #inclib "ext"
from this point you can mix PB ext with FP ext.
Joshy
Charles Pegge
22-03-2010, 00:05
This is the candidate thinCoreFB. It still has a few differences from the PB version as well as the additions but it is much easier to maintain than the previous one.
I have included your EXT code directly.
You are welcome to improve it, Joshy :)
Charles
D.J.Peters
23-03-2010, 16:15
hi Charles
do you have in your assembler "repertoire" a function that converts 10 byte floats to an ascii string ?
I'm sure i can do it self but why if you have a working version.
Joshy
Charles Pegge
23-03-2010, 18:16
Hi Joshy,
Converting float to ascii is a dragon I have yet to conquer! It is one of those beasts which are a lot harder than they first appear, taking all the possible outputs into consideration. I think it will take me about 2 days, but if you can do it faster or find ready-made code then please go ahead :)
Charles
Charles Pegge
26-03-2010, 13:06
Phew! That was hard work.
I studied the MASM FPU code to get the correct power scaling code, and wrote it in Oxygen first before porting to FreeBasic, so it looks a bit unusual. It was much easier to do it this way with block structured programming.
My code will support +0 -0 #INF #-INF #qNAN #sNAN. You can also control the decimal places and scientific notation etc.
I have patched it into your EXT operator set, Joshy.
Charles
PS: See attachment further on
D.J.Peters
27-03-2010, 03:51
hi Charles
"That was hard work." yes but a good job ;)
dim as ext a=1,b=3
dim as ext c=a/b
do you know why EXTended data type gives you only 16 decimal places ?
this are the same places as you would use double 1.0/3.0
Joshy
Charles Pegge
27-03-2010, 09:03
The final 2 digits are unreliable, and change as variable A is scaled 1 .. 1E+100 etc.
But I think it might also be cumulative errors inherent in FBSTP
you can see the last digits by setting num.dp to 17, which I have done below
Charles
PS: this Zip has been corrected (1 asm bug). I have withdrawn the previous one.
Charles far be it for me to give advice to master, but I wrote an FtoA function long ago and it reliably gives 18 digit output, one thing I got wrong was in checking for NaN's, I would post code but it's a mess and looking at the code I don't understand how some parts work (it's been a long time since i wrote it).
one thought though, why not just output the maximum digits and use cast to double if you want less digits?
I know it will only work as long as the extended is within the range of double, so it coud be a problem.
Charles Pegge
28-03-2010, 11:42
Hi Jack,
Yes there is something strange going on. With the Oxygen version, I get an accurate 0.333333333333333. But with large powers, say 1e+200 / 3 the final 2 digits are out: 3.33333333333333320E+19.
I'll keep on experimenting.
Could you try running some big thirds and see what results you get with your code?
Charles
D.J.Peters
19-05-2013, 14:43
I lost all my old thinbasic module source codes and can't remember how I called a thinBasic script callback sub with one long param ?
sub MyCallBack(byval StreamID as long)
' ...
end sub
Can anyone explain it again please.
thank you
Joshy
USES FreeSound
dim hStream as long = CreateNewMP3Stream("intro_music.mp3")
MP3StreamSetEndCallback(hStream, "MyCallBack")
StartMP3Stream(hStream)
' ...
sub MyCallBack(byval StreamID as long) ' <--- how call it with one long param ?
printl "end of MP3 stream !" + str$(StreamID)
end sub
D.J.Peters
20-05-2013, 04:00
I know how to parse the name of the callback sub
and how i call it from module.
But how I can set the long param before i made the call ?
Would be really great if someone can give me the right hint.
By the way exist source code from a module that use callbacks with params ?
My curent work is interrupted without your help.
Joshy
ReneMiner
20-05-2013, 09:24
maybe this helps?
'----------------------------------------------------------------------------
'thinBasic_FunctionSimpleCall_ByPtr
'----------------------------------------------------------------------------
' Call a script function and optionally returns it value (numeric or string)
' This function permits to call script callback functions passing automatic
' pseudo callbacks variables
' USE only when in need of a callback function from module
'----------------------------------------------------------------------------
Declare Function thinBasic_FunctionSimpleCall_ByPtr _
Lib "thinCore.DLL" _
Alias "thinBasic_FunctionSimpleCall_ByPtr" _
( _
ByVal FunctionPtr As Long , _ '---PTR to function returned by thinBasic_FunctionGetPtr or other way
Optional _
ByVal ptrEXT As Ext Ptr , _ '---Used to get back from the called function a numeric value
ByVal ptrSTR As String Ptr , _ '---Used to get back from the called function a string value
ByVal IsCallBack As Long , _
ByVal lCBHNDL As Long , _
ByVal lCBMSG As Long , _
ByVal lCBCTL As Long , _
ByVal lCBCTLMSG As Long , _
ByVal lCBLPARAM As Long , _
ByVal lCBWPARAM As Long , _
ByVal lCBNMCODE As Long , _
ByVal lCBNMHDR As Long , _
ByVal lCBNMHWND As Long , _
ByVal lCBNMID As Long _
) As Long
'----------------------------------------------------------------------------
'thinBasic_FunctionGetPtr
'----------------------------------------------------------------------------
'----------------------------------------------------------------------------
Declare Function thinBasic_FunctionGetPtr _
Lib "thinCore.DLL" _
Alias "thinBasic_FunctionGetPtr" _
( _
ByVal fName As String _
) As Long
But maybe I'm on the wrong track here...
Charles Pegge
20-05-2013, 10:49
I have used this one successfully with an Oxygen script: It supports an array of parameters (stride 8 bytes) , and also returns double, string and long types from thinBasic
From thincore
'----------------------------------------------------------------------------
'thinBasic_FunctionCall_ByPtr
'----------------------------------------------------------------------------
' Call a script function and optionally returns it value (numeric or string)
' This function permits to call script functions passing parameters
' Parameters are passed using a shared memory area made by a sequence of DOUBLEs
' (8 bytes) one for each parameter to be passed.
' The paramaters memory area will be interpreted by thinBasic core engine
' depending by parameters declaration made in script.
'
' So far the following type of parameters are supported:
' - numeric parameters passed ByVal up to DOUBLE range
'
' Example: if programmer wants to pass 2 parameters, set lModParams = 2 and setup
' a 16 bytes memory area (2 params * 8 bytes each) where to store the 2 parameter
' values.
'----------------------------------------------------------------------------
Declare Function thinBasic_FunctionCall_ByPtr _
Lib "thinCore.DLL" _
Alias "thinBasic_FunctionCall_ByPtr" _
( _
ByVal FunctionPtr As Long , _ '---PTR to script function
ByVal lModParams As Long , _ '---MANDATORY: number of params module is passing
ByVal lModParamsPtr As Long , _ '---MANDATORY: pointer to a memory area where to find parameters (8 bytes for each parameter)
Optional _ '---If no need to get back script function result value, do not indicate the next 2 parameters
ByVal ptrDOUBLE As Double Ptr , _ '---Pointer to DOUBLE that will get back script function return value in case of numeric
ByVal ptrSTR As BSTR Ptr _ '---Pointer to a OLE32 dynamic string handle that will get back script function return value in case of string
) As Long
D.J.Peters
20-05-2013, 15:25
Thank you both.
Now i can get it
it was missing in my "thinCore.bi" file.
than you
Joshy