Page 1 of 1

Processing events in console?

Posted: Tue Apr 09, 2019 8:02 pm
by vwidmer
How do you do something like this with a console app? without having to openwindow?

Thanks

Code: Select all

  ; All our custom events
  Enumeration #PB_Event_FirstCustomValue
    #EventBeginProcessing
    #EventProcessingFinished
  EndEnumeration
  
  
  Procedure Thread(Value)
    PostEvent(#EventBeginProcessing)
    
    Delay(3000)
    PostEvent(#EventProcessingFinished)
  EndProcedure
  
  OpenWindow(0, 200, 200, 100, 100, "PostEvent")
  
  CreateThread(@Thread(), 0)
  
  Repeat
    Event = WaitWindowEvent()
    
    Select Event
      Case #EventBeginProcessing
        Debug "Thread begin processing "
        
      Case #EventProcessingFinished
        Debug "Thread processing finished"
    EndSelect
    
  Until Event = #PB_Event_CloseWindow

Re: Processing events in console?

Posted: Tue Apr 09, 2019 8:22 pm
by infratec
Hi,

if you want the events, you need a window.
But you can use a 'small' window and set the invisible flag (#PB_Window_Invisible)

Else you can use an own construct with a semaphore and use WaitSemaphore() as WaitWindowEvent() replacement.

Re: Processing events in console?

Posted: Tue Apr 09, 2019 8:41 pm
by infratec
As a starting point:

Code: Select all

Enumeration
  #EventBeginProcessing
  #EventProcessingFinished
EndEnumeration

Structure EventListStructure
  Event.i
  EventData.i
EndStructure

Structure EventStructure
  Semaphore.i
  List EventList.EventListStructure()
EndStructure

Global GlobalEvent.EventStructure

Procedure SendEvent(Event.i, EventData.i=0)
  AddElement(GlobalEvent\EventList())
  GlobalEvent\EventList()\Event = Event
  GlobalEvent\EventList()\EventData = EventData
  SignalSemaphore(GlobalEvent\Semaphore)
EndProcedure


Procedure Thread1(*Dummy)
  SendEvent(#EventBeginProcessing)
  Delay(3000)
  SendEvent(#EventProcessingFinished)
EndProcedure




GlobalEvent\Semaphore = CreateSemaphore()

CreateThread(@Thread1(), 0)

Repeat
  
  WaitSemaphore(GlobalEvent\Semaphore)
  
  If LastElement(GlobalEvent\EventList())
    Select GlobalEvent\EventList()\Event
      Case #EventBeginProcessing
        Debug "EventBeginProcessing"
      Case #EventProcessingFinished
        Debug "EventProcessingFinished"
    EndSelect
    DeleteElement(GlobalEvent\EventList())    
  EndIf
  
ForEver

Re: Processing events in console?

Posted: Tue Apr 09, 2019 9:05 pm
by infratec
As Module

Code: Select all

;
; ConsoleEvents.pbi
;
; https://www.purebasic.fr/english/viewtopic.php?p=535048#p535048
;


DeclareModule ConsoleEvents
  Declare PostConsoleEvent(Event.i, EventData.i=0)
  Declare.i WaitConsoleEvent()
  Declare.i ConsoleEvent()
  Declare.i ConsoleEventData()
EndDeclareModule

Module ConsoleEvents
  
  EnableExplicit
  
  Structure EventListStructure
    Event.i
    EventData.i
  EndStructure
  
  Structure EventStructure
    Semaphore.i
    List EventList.EventListStructure()
  EndStructure
  
  Global ConsoleEvent.EventStructure
  Global CurrentEvent.EventListStructure
  
  Procedure PostConsoleEvent(Event.i, EventData.i=0)
    
    If Not ConsoleEvent\Semaphore
      ConsoleEvent\Semaphore = CreateSemaphore()
    EndIf
    
    AddElement(ConsoleEvent\EventList())
    ConsoleEvent\EventList()\Event = Event
    ConsoleEvent\EventList()\EventData = EventData
    SignalSemaphore(ConsoleEvent\Semaphore)
  EndProcedure
  
  
  Procedure.i WaitConsoleEvent()
    
    Protected ReturnValue.i
    
    
    If Not ConsoleEvent\Semaphore
      ConsoleEvent\Semaphore = CreateSemaphore()
    EndIf
    
    ReturnValue = -1
    
    WaitSemaphore(ConsoleEvent\Semaphore)
    
    If FirstElement(ConsoleEvent\EventList())
      CopyStructure(ConsoleEvent\EventList(), CurrentEvent, EventListStructure)
      DeleteElement(ConsoleEvent\EventList())
      ReturnValue = CurrentEvent\Event
    EndIf
    
    ProcedureReturn ReturnValue
    
  EndProcedure
  
  
  Procedure.i ConsoleEvent()
    
    Protected ReturnValue.i
    
    
    If Not ConsoleEvent\Semaphore
      ConsoleEvent\Semaphore = CreateSemaphore()
    EndIf
    
    ReturnValue = -1
    
    If TrySemaphore(ConsoleEvent\Semaphore)
      
      If FirstElement(ConsoleEvent\EventList())
        CopyStructure(ConsoleEvent\EventList(), CurrentEvent, EventListStructure)
        DeleteElement(ConsoleEvent\EventList())
        ReturnValue = CurrentEvent\Event
      EndIf
      
    EndIf
    
    ProcedureReturn ReturnValue
    
  EndProcedure
  
  
  Procedure.i ConsoleEventData()
    ProcedureReturn CurrentEvent\EventData
  EndProcedure
  
EndModule


CompilerIf #PB_Compiler_IsMainFile
  
  EnableExplicit
  
  CompilerIf Not #PB_Compiler_Thread
    CompilerError "Enable Threadsafe in compiler options"
  CompilerEndIf
  
  Enumeration
    #EventBeginProcessing
    #EventProcessingFinished
  EndEnumeration
  
  
  Procedure Thread1(*Dummy)
    ConsoleEvents::PostConsoleEvent(#EventBeginProcessing, 1)
    ConsoleEvents::PostConsoleEvent(#EventBeginProcessing, 2)
    ConsoleEvents::PostConsoleEvent(#EventBeginProcessing, 3)
    Delay(3000)
    ConsoleEvents::PostConsoleEvent(#EventProcessingFinished, 123)
  EndProcedure
  
  
  Define Event.i, Exit.i
  
  CreateThread(@Thread1(), 0)
  
  Repeat
    
    Event = ConsoleEvents::WaitConsoleEvent()
    ;Event = ConsoleEvents::ConsoleEvent()
    
    Select Event
      Case #EventBeginProcessing
        Debug "EventBeginProcessing"
        Debug ConsoleEvents::ConsoleEventData()
      Case #EventProcessingFinished
        Debug "EventProcessingFinished"
        Debug ConsoleEvents::ConsoleEventData()
        Exit = #True
    EndSelect
    
  Until Exit
  
CompilerEndIf

Re: Processing events in console?

Posted: Tue Apr 09, 2019 11:02 pm
by vwidmer
Thanks that helped alot, thanks for the module as well..

Re: Processing events in console?

Posted: Wed Apr 10, 2019 12:31 am
by davido
@infratec,
Thank you for posting this example. I found it very instructive. :D

Re: Processing events in console?

Posted: Wed Apr 10, 2019 7:42 am
by infratec
I had to change the module above.

It was not FIFO it was FILO :(

I fixed this and simplified also the list handling.

Re: Processing events in console?

Posted: Wed Apr 10, 2019 10:12 am
by Little John
Hi infratec,

I'd also like to thank you for that event handling module!

BTW: Is it possible in PB that a thread calls other threads?
If so, then I think your module could be well used as a basis for simulation programs.

Re: Processing events in console?

Posted: Wed Apr 10, 2019 10:16 am
by infratec
Little John wrote:BTW: Is it possible in PB that a thread calls other threads?
What do you mean with calling?

Creating other threads, or exchange data with other threads?

Re: Processing events in console?

Posted: Wed Apr 10, 2019 1:23 pm
by Little John
Oops, sorry! :oops:

I wanted to ask whether a thread can create other threads,
or whether only the main program may call the CreateThread() function.

Re: Processing events in console?

Posted: Wed Apr 10, 2019 2:03 pm
by infratec
Simple Test:

Code: Select all

Procedure Thread2(*Dummy)
  
  Debug "T2"
  Delay(1000)
  
EndProcedure



Procedure Thread1(*Dummy)
  
  Debug "T1"
  For i = 0 To 2
    Delay(3000)
    CreateThread(@Thread2(), 0)
  Next i
  
  Delay(3000)
  
EndProcedure


T1 = CreateThread(@Thread1(), 0)

WaitThread(T1)
So: no problem