Page 1 of 2

Background running procedure

Posted: Sun Mar 07, 2010 2:50 pm
by charvista
I would like to run a procedure in background, for example a clock, since I cannot imagine a clock being stopped :mrgreen:
So far, I have in the event loop a #PB_Event_Timer, but when you click on the menubar of this application, the clock stops.
I would like to make it running forever, uninterrupted. How do I do that ?
Snippet of what I have so far:

Code: Select all

    Win = OpenWindow(#PB_Any, 0, 100,500, 300, "App" )
    AddWindowTimer(Win,111,1000)
    TextGadget(1,300,10,500,20,"")
    BodyMenu = CreateMenu(#PB_Any, WindowID(Win))
    MenuTitle("Databases")
    MenuItem(0001, "Database1s"+Chr(9)+"Ctrl+T")
    MenuItem(0009, "Database2"+Chr(9)+"Ctrl+Y")
    Repeat
        Event = WaitWindowEvent()
        Select Event
            Case #PB_Event_Timer
                If EventTimer()=111
                    SetGadgetText(1,FormatDate("%hh:%ii:%ss",Date()))
                EndIf
            Case #PB_Event_CloseWindow
                ExitEventLoop = #True
        EndSelect
    Until ExitEventLoop

Re: Background running procedure

Posted: Sun Mar 07, 2010 3:18 pm
by RASHAD
Hi charvista
Very quick snippet

Code: Select all

Procedure YourProcedure(*Value)
  Repeat
    SetGadgetText(1,FormatDate("%hh:%ii:%ss",Date()))
    Delay(50)
  ForEver

EndProcedure
  
   Win = OpenWindow(#PB_Any, 0, 100,500, 300, "App" )
    AddWindowTimer(Win,111,1000)
    TextGadget(1,300,10,500,20,"")
    BodyMenu = CreateMenu(#PB_Any, WindowID(Win))
    MenuTitle("Databases")
    MenuItem(0001, "Database1s"+Chr(9)+"Ctrl+T")
    MenuItem(0009, "Database2"+Chr(9)+"Ctrl+Y")
    Thread = CreateThread(@YourProcedure(), *Value)

    
    Repeat
        
        Event = WaitWindowEvent()
        Select Event
;             Case #PB_Event_Timer
;                 If EventTimer()=111
;                     SetGadgetText(1,FormatDate("%hh:%ii:%ss",Date()))
;                 EndIf
            Case #PB_Event_CloseWindow
                ExitEventLoop = #True
        EndSelect
    Until ExitEventLoop

Re: Background running procedure

Posted: Sun Mar 07, 2010 3:46 pm
by charvista
CreateThread() is perfect. Your very quick example worked very well Rashad. Many thanks!

Re: Background running procedure

Posted: Sun Mar 07, 2010 4:09 pm
by ts-soft

Code: Select all

Procedure TimerCB(hWnd, uMsg, idEvent, dwTime)
  If idEvent = 111
    SetGadgetText(1, FormatDate("%hh:%ii:%ss", Date()))
  EndIf
EndProcedure

Win = OpenWindow(#PB_Any, 0, 100, 500, 300, "App" )
;AddWindowTimer(Win, 111, 1000)
SetTimer_(WindowID(Win), 111, 1000, @TimerCB())
TextGadget(1, 300, 10, 500, 20, "")
BodyMenu = CreateMenu(#PB_Any, WindowID(Win))
MenuTitle("Databases")
MenuItem(0001, "Database1s" + Chr(9) + "Ctrl+T")
MenuItem(0009, "Database2" + Chr(9) + "Ctrl+Y")
Repeat
  Event = WaitWindowEvent()
  Select Event
;     Case #PB_Event_Timer
;       If EventTimer() = 111
;         SetGadgetText(1, FormatDate("%hh:%ii:%ss", Date()))
;       EndIf
    Case #PB_Event_CloseWindow
      ExitEventLoop = #True
  EndSelect
Until ExitEventLoop

KillTimer_(WindowID(win), 111)

Re: Background running procedure

Posted: Sun Mar 07, 2010 4:30 pm
by charvista
Hi Thomas (ts-soft)
Ah, you have a different way, using API's... It's good to know how to do that. Thank you, but when comparing your code and Rashad's, I will take Rashad's for two reasons:
1) CreateThread() is an internal PB function
2) and the main reason is that with your code the TextGadget is flickering, while Rashad's does not...

Re: Background running procedure

Posted: Sun Mar 07, 2010 4:44 pm
by ts-soft
charvista wrote: 1) CreateThread() is an internal PB function
If you require it for other os, you are right
charvista wrote: 2) and the main reason is that with your code the TextGadget is flickering, while Rashad's does not...
i can't see any flickering, i see only my version requires less cpu-usage :wink:

greetings
Thomas

Re: Background running procedure

Posted: Sun Mar 07, 2010 5:00 pm
by charvista
charvista wrote:2) and the main reason is that with your code the TextGadget is flickering, while Rashad's does not...


i can't see any flickering, i see only my version requires less cpu-usage :wink:
Well, I do... very clearly, without glasses :wink:

Re: Background running procedure

Posted: Mon Mar 08, 2010 3:38 am
by SFSxOI
ts-soft's version does not flicker here, works well.

Re: Background running procedure

Posted: Mon Mar 08, 2010 12:48 pm
by Baldrick
ts-soft's function looks good to me & is only being called 1 time every 1000ms, I can't see how this could possibly flicker?

Re: Background running procedure

Posted: Mon Mar 08, 2010 1:24 pm
by Trond
Rashads' code flickers a bit here.

Re: Background running procedure

Posted: Mon Mar 08, 2010 2:54 pm
by Mahan
Hmm, SetGadgetText() from within a thread, is that really ok?

Unless SetGadgetText() does some kind of synchronization in the background this looks pretty dangerous to me. (Long ago I did the equivalent of this in Delphi which resulted in random program crashes.)

Re: Background running procedure

Posted: Mon Mar 08, 2010 3:12 pm
by srod
It is fine providing the main process is running an event loop and thus retrieving messages etc. Personally, if using a thread, I'd be tempted to create the text gadget itself in the thread.

Re: Background running procedure

Posted: Mon Mar 08, 2010 4:38 pm
by charvista
Regarding the flickering, I had only this flickering on a Vista machine. On my Win7 both Rashad and ts-soft are perfect. The flickering is just the refreshing of the text.

I have encountered problems with Threads with StartDrawing() where I believe there is a conflict between the drawing in the normal program and the drawing in the thread. I'll post an example tomorrow as I don't have the code here.
Be ready to find a solution! :wink:

Re: Background running procedure

Posted: Mon Mar 08, 2010 4:40 pm
by srod
Both perfect here on Vista.

Re: Background running procedure

Posted: Tue Mar 09, 2010 12:49 pm
by charvista
Then maybe my Vista computer is too slow.

But now the problem I promised yesterday.
I made a small program that shows a clock running in background using CreateThread(). When you start the program all is going fine. But when you click on the menu File/Mayan Date Countdown it will open a new window with his own CreateThread() counting down the number of seconds until 21st December 2012, the famous "End of the Mayan Era". I had to add a KillThread() in the main window, otherwise the countdown window won't work. My goal is of course that both windows are running (clock & countdown) as BACKGROUND operation.
Either I don't know how to do that, or there is probably a conflict between the StartDrawing() of both operations.
I tried to keep the code as small as simple as possible.

Code: Select all

Declare zMayanDateCountDown(*Interval)

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

Procedure zMaya(ParentWin)
    DisableWindow(ParentWin, 1)
    Win1=OpenWindow(#PB_Any,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)
    Thread1 = CreateThread(@zMayanDateCountDown(), 50)
    Repeat
        Event = WaitWindowEvent()
        Select Event
            Case #PB_Event_CloseWindow
                ExitEventLoop = #True
            ;EndCase
        EndSelect
    Until ExitEventLoop
    KillThread(Thread1) ; this line is okay since we leave the window
    CloseWindow(Win1)
    DisableWindow(ParentWin, 0)
EndProcedure

Procedure zClockText(Text.s)
    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

Procedure zMayanText(Text.s)
    StartDrawing(ImageOutput(#Image_12))
        DrawImage(ImageID(#Image_11), 0, 0)
        DrawingMode(#PB_2DDrawing_Transparent)
        DrawingFont(FontID(#Font_1))
        DrawText(50, 120, Text, $000000)
        DrawText(47, 117, Text, $0000FF)
    StopDrawing()
    SetGadgetState(#Gad_Image_11, ImageID(#Image_12))
EndProcedure

Procedure zMayanDateCountDown(*Interval)
    Repeat
        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
        zMayanText(Str(Remaining))
        Delay(*Interval)
    ForEver
EndProcedure

Procedure zClock(*Interval)
    Repeat
        zClockText(FormatDate("%yyyy-%mm-%dd     %hh:%ii:%ss",Date()))
        Delay(*Interval)
    ForEver
EndProcedure

;StartProgram -------------------------------------------------------------------------------------------------------------------     
    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")
    Thread = CreateThread(@zClock(), 50)
;EndProgram
;StartEventLoop ----------------------------------------------------------------------------------------------------------------------       
    Repeat
        Event = WaitWindowEvent()
        Select Event
            Case #PB_Event_CloseWindow
                ExitEventLoop = #True
            Case #PB_Event_Menu
                Select EventMenu()
                    Case 0001
                        KillThread(Thread) ;this line should not be there............ but it avoids conflicts... Solution???
                        ; and due to the killthread, you cannot request it a second time
                        zMaya(Win)
                    ;EndCase
                EndSelect
            ;EndCase
        EndSelect
    Until ExitEventLoop
;EndEventLoop