Page 2 of 2

Re: Background running procedure

Posted: Tue Mar 09, 2010 1:04 pm
by srod
Works fine here if I remove the KillThread(). You have set the threadsafe compiler switch haven't you?

Re: Background running procedure

Posted: Tue Mar 09, 2010 2:58 pm
by Baldrick
Based loosley around ur code Charvista & pretty rough, unchecked, etc, here is a version using Settimer_()

Code: Select all

    ;StartEnumeration
        Enumeration
            #Win1
            #Font_1
            #Image_1
            #Image_2
            #Image_11
            #Image_12
            #Gad_Image_1
            #Gad_Image_11
            #TmrA
            #TmrB
        EndEnumeration
    ;EndEnumeration
      
    Procedure zMayanDateCountDown()
            Maya=Date(2012,12,21,0,0,0) ; Mayan Date assumed to be 21st Dec 2010, Time unknown, so midnight is assumed
            Today=Date()
            Remaining=Maya-Today
        StartDrawing(ImageOutput(#Image_12))
            DrawImage(ImageID(#Image_11), 0, 0)
            DrawingMode(#PB_2DDrawing_Transparent)
            DrawingFont(FontID(#Font_1))
            DrawText(50, 120, Str(Remaining), $000000)
            DrawText(47, 117, Str(Remaining), $0000FF)
        StopDrawing()
        SetGadgetState(#Gad_Image_11, ImageID(#Image_12))
    EndProcedure
    
    Procedure zMaya(ParentWin) 
       Shared Tmr2
        DisableWindow(ParentWin, 1)
        Win1=OpenWindow(#Win1,0,0,400,300,"Mayan Date Countdown",#PB_Window_SystemMenu,WindowID(ParentWin))
        h = LoadImage(#Image_11, #PB_Compiler_Home+"Examples\Sources\Data\terrain_texture.jpg")
        ImageGadget(#Gad_Image_11, 0, 0, 400, 300, h)
        DisableGadget( #Gad_Image_11, 1 )
        CreateImage(#Image_12, 400,300)
        Tmr2 = SetTimer_(WindowID(#Win1),#TmrB,200,@zMayanDateCountDown())
    EndProcedure
    
    Procedure zClockText()
      Text.s=FormatDate("%yyyy-%mm-%dd     %hh:%ii:%ss",Date())
        StartDrawing(ImageOutput(#Image_2))
            DrawImage(ImageID(#Image_1), 0, 0)
            DrawingMode(#PB_2DDrawing_Transparent)
            DrawingFont(FontID(#Font_1))
            DrawText(150, 400, Text, $000000)
            DrawText(147, 397, Text, $0000FF)
        StopDrawing()
        SetGadgetState(#Gad_Image_1, ImageID(#Image_2))
    EndProcedure


        LoadFont(#Font_1,"Arial",50, #PB_Font_Bold)
        UseJPEGImageDecoder()
        Win = OpenWindow(#PB_Any, 0, 0, 1024, 600, "Applications", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
        h = LoadImage(#Image_1, #PB_Compiler_Home+"Examples\Sources\Data\terrain_texture.jpg")
        ImageGadget(#Gad_Image_1, 0, 0, 1024, 600, h)
        DisableGadget( #Gad_Image_1, 1 )
        CreateImage(#Image_2, 1024, 600)
        BodyMenu = CreateMenu(#PB_Any, WindowID(Win))
        MenuTitle("File")
        MenuItem(0001, "Mayan Date Countdown")
        tmr1=SetTimer_(WindowID(Win),#TmrA,200,@zClockText()) 
               
        Repeat
            Event = WaitWindowEvent()
            Select Event
                Case #PB_Event_CloseWindow
                  Select EventWindow() 
                    Case Win
                      ExitEventLoop = #True
                    Case #Win1
                        If Tmr2 
                          KillTimer_(WindowID(#Win1),#TmrB) 
                          Tmr2=0
                        EndIf
                      CloseWindow(#Win1) 
                      DisableWindow(Win,0) 
                  EndSelect 
                Case #PB_Event_Menu
                    Select EventMenu()
                        Case 0001 
                          zMaya(Win)
                    EndSelect
            EndSelect
        Until ExitEventLoop
        
        If tmr1 
          KillTimer_(WindowID(Win),#TmrA) 
        EndIf 
        If Tmr2 
          KillTimer_(WindowID(#Win1),#TmrB) 
        EndIf 

Re: Background running procedure

Posted: Tue Mar 09, 2010 5:54 pm
by charvista
@srod
No, I hadn't set the threadsafe compiler option. This is the reason why it did not work. With this option checked and KillThread() removed it now works fine here too. Thank you for the solution!

@Baldrick
Your code works without the threadsafe option checked! :mrgreen: Thank you to you too for the solution!

@PB Team:
Because CreateThread() was new to me, as well the variants like KillThread(), I was not yet aware that there was a compiler option for that. And if I ever saw it before, I did not know what it was. Therefore, to help future users of PureBasic with Threads, I think it is a good idea to add a small reminder that the threadsafe option should be checked to avoid unexpected behaviour, on the CreateThread() help-page. :wink:

Re: Background running procedure

Posted: Tue Mar 09, 2010 5:57 pm
by srod
The Threads overview in the PB user manual discusses the Threadsafe compiler switch etc. You didn't read it carefully enough! :wink:

Re: Background running procedure

Posted: Tue Mar 09, 2010 6:11 pm
by charvista
Srod, I must admit that you are completely right! You just showed me the right page to read!! :D
Now I understand Threads much better.
It's written that one must be careful with threads... indeed I could jump to the past or be back to the future!! :mrgreen:

Re: Background running procedure

Posted: Thu Mar 11, 2010 10:01 am
by RASHAD
Hi charvista
Today I got some time to play with your code, may be it is too late
But late better than nothing

Code: Select all

;StartEnumeration
    Enumeration
        #Font_1
        #Image_1
        #Image_2
        #Image_11
        #Image_12
        #Gad_Image_1
        #Gad_Image_11
    EndEnumeration
;EndEnumeration

Procedure zClock(*Interval)
    Repeat
    StartDrawing(ImageOutput(#Image_2))
        DrawImage(ImageID(#Image_1), 0, 0)
        DrawingMode(#PB_2DDrawing_Transparent)
        DrawingFont(FontID(#Font_1))
        DrawText(150, 450,FormatDate("%yyyy-%mm-%dd     %hh:%ii:%ss",Date()), $000000)
        DrawText(147, 447,FormatDate("%yyyy-%mm-%dd     %hh:%ii:%ss",Date()), $0000FF)
    StopDrawing()
    SetGadgetState(#Gad_Image_1, ImageID(#Image_2))
        Maya=Date(2012,12,21,0,0,0) ; Mayan Date assumed to be 21st Dec 2010, Time unknown, so midnight is assumed
        Today=Date()
        Remaining=Maya-Today
    StartDrawing(ImageOutput(#Image_12))
        DrawImage(ImageID(#Image_11), 0, 0)
        DrawingMode(#PB_2DDrawing_Transparent)
        DrawingFont(FontID(#Font_1))
        DrawText(50, 120, Str(Remaining), $000000)
        DrawText(47, 117,Str(Remaining), $0000FF)
    StopDrawing()
    SetGadgetState(#Gad_Image_11, ImageID(#Image_12))
       Delay(*Interval)
    ForEver
EndProcedure

;StartProgram -------------------------------------------------------------------------------------------------------------------     
    LoadFont(#Font_1,"Arial",50, #PB_Font_Bold)
    UseJPEGImageDecoder()
    OpenWindow(0, 0, 0, 1024, 600, "Applications", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    h = LoadImage(#Image_1, #PB_Compiler_Home+"Examples\Sources\Data\terrain_texture.jpg")
    ImageGadget(#Gad_Image_1, 0, 0, 1024, 600, h)
    CreateImage(#Image_2, 1024, 600)
    BodyMenu = CreateMenu(#PB_Any, WindowID(Win))
    MenuTitle("File")
    MenuItem(0001, "Mayan Date Countdown")
    OpenWindow(1,0,0,400,300,"Mayan Date Countdown",#PB_Window_SystemMenu|#PB_Window_WindowCentered|#PB_Window_Invisible,WindowID(0))
    h1 = LoadImage(#Image_11, #PB_Compiler_Home+"Examples\Sources\Data\terrain_texture.jpg")
    ImageGadget(#Gad_Image_11, 0, 0, 400, 300, h1)
    CreateImage(#Image_12, 400,300)    
    Thread = CreateThread(@zClock(),50)
;EndProgram
;StartEventLoop ----------------------------------------------------------------------------------------------------------------------       
    Repeat
        Event = WaitWindowEvent()
        Select Event
            Case #PB_Event_CloseWindow
                If GetActiveWindow() = 1
                    HideWindow(1, 1)
                 Else                 
                   ExitEventLoop = #True
                EndIf
            Case #PB_Event_Menu
                Select EventMenu()
                    Case 0001
                        HideWindow(1, 0)
                    ;EndCase
                EndSelect
            ;EndCase
        EndSelect
    Until ExitEventLoop
;EndEventLoop

Re: Background running procedure

Posted: Thu Mar 11, 2010 11:41 am
by charvista
Hi Rashad
Never too late to learn :)
Cool, you centered the Mayan countdown window and gave the ability to close the main window while the Mayan window is still open.

I wrote this program to understand the concept of background running programs.
In my apps, it is a bit more complicated. As my goal is to display a running clock in every window that the user opens in the right lower corner (like Windows), I have a global array to bring some data to each zClock(), because the Thread can enter ONLY ONE integer variable, and that's not enough. I need at least two. So my next question is:
How can I know in which application level I am now?
The procedure with the menu is always level 0. When making a choice from the menu, another procedure is called, that's level 1. If this procedure calls another procedure, it becomes level 2 and so on.
If I have a level number, then my global array can be a two-dimensioned array Array(Level, 0)=value1 and Array(Level,1)=value2.
I thought I could get the window handle given by #PB_Any when doing a Win=OpenWindow(#PB_Any,...) but it returns a too large and random number...
Any ideas?

Re: Background running procedure

Posted: Thu Mar 11, 2010 12:01 pm
by RASHAD
charvista
Hi again
If you faced any problem just put some code,and the guys here will give you their best shots
But in case you will need more than one thread you have to learn how to CreateMutex() to sync. between
the different threads
I personaly like PureBasic Threads because I like to control what I am doing by myself
Threads has advantages and disadv. and so settime_() too it is not threadsafe class by itself
Beside it is controled by Windows so you will notice that there is a gap in time between your application
and the settime thread
You are going very fast charvista but be careful with your comments man,will you ?

Re: Background running procedure

Posted: Thu Mar 11, 2010 12:45 pm
by RASHAD
charvista
I think you can create thread with more than one variable
See next ,Try and give us your feedback

Code: Select all

Procedure RunThread(param_1,param_2,param_3,param_4)
 ;.......................
 ;.......................
 ;.......................
 
EndProcedure


Procedure zClock(Parameter)
  Shared param_1.i,param_2.i,param_3.i,param_4.i
  RunTread(x_1, x_2,x_3,x_4)
EndProcedure

;....................................
;....................................
;....................................

Thread = CreateThread(@zClock(), Parameter)

Re: Background running procedure

Posted: Mon Mar 15, 2010 8:41 pm
by charvista
Hi RASHAD
Sorry for the delay, I have been thinking about that all.
Your solution is smart -- using Shared variables.
After thinking and experiencing, I prefer to use global variables, these are also shared everywhere.
A global two-dimensioned array was the ideal solution to me.

Code: Select all

Global Dim _AppValue.i(100,1) ; Application, SubValue
Only problem was the procedure level to get because every window has his own values, for example #ImageGadget.
I found a solution.
Every time I do a OpenWindow(), I call zGetApp() then I fill the _AppValue() array with the necessary values

Code: Select all

    zGetApp(@App)
    PokeI(*App,App)
    _AppValue(PeekI(*App),0)=Image4 ; image number - will never be 0
    _AppValue(PeekI(*App),1)=ImGad4 ; image gadget number
And this is the zGetApp() procedure:

Code: Select all

Procedure zGetApp(*App.integer)
    For i=1 To 100
        If _BottomLine(i,0)=0
            PokeI(*App,i)
            Break
        EndIf
    Next
EndProcedure
Then I can add a thread

Code: Select all

Thread=CreateThread(@zAppClock(), App)
and when the window is going to be closed, I kill the thread and set the first value to 0 to free it to other windows

Code: Select all

KillThread(Thread) : _BottomLine(App,0)=0
OK, I don't know if you understand this as this is rather complex, but it works. The variable App is the level number.
Edit: In my case CreateMutex() is not necessary, but I do understand the concept of the Mutex.

Re: Background running procedure

Posted: Mon Mar 15, 2010 10:54 pm
by cas
charvista wrote:because the Thread can enter ONLY ONE integer variable, and that's not enough. I need at least two.
You sure that it's not enough? Only one integer variable is all we need, we only pass pointer to structured variable.
Here is one quick example:

Code: Select all

EnableExplicit

Debug "****** Program start! ******"

Structure variables_for_thread
  first_variable.i
  second_variable.i
  third.b
  fourth.s
  fifth.c[10]
EndStructure

Procedure thread1(*struct.variables_for_thread)
  Debug "*** Thread start! ***"
  Debug *struct\first_variable.i
  Debug *struct\second_variable.i
  Debug *struct\third.b
  Debug *struct\fourth.s
  Debug *struct\fifth.c[0]
  Debug *struct\fifth.c[1]
  Debug *struct\fifth.c[2]
  Debug *struct\fifth.c[3]
  
  Define i
  For i=3 To 9
    Debug *struct\fifth.c[i]
  Next
  Debug "*** Thread end! ***"
EndProcedure


Define myvariables.variables_for_thread
myvariables\first_variable.i=5
myvariables\second_variable.i = 6
myvariables\third.b=1
myvariables\fourth.s="test string"
myvariables\fifth.c[0]=255
myvariables\fifth.c[1]=5
myvariables\fifth.c[2]=10
myvariables\fifth.c[3]=15
myvariables\fifth.c[5]=25
myvariables\fifth.c[8]=40

Define thread = CreateThread(@thread1(),myvariables)

WaitThread(thread)

Debug "****** Program end! ******"

Re: Background running procedure

Posted: Tue Mar 16, 2010 10:18 am
by charvista
Hmmm, interesting. Thanks for the idea, CAS.
I have to study this as I have never used structures before. Maybe it will simplify my solution even more.
I know PureBasic for 2 years now, but I really began using it for about 1 year.
After learning the basic language, how to draw pictures, write text on pictures, using floating numbers, memory pointers, threads, now I think it's time to look at the structures much closer. Seems it's powerful as it also use memory pointers.
And later the SQLite......