Processing events in console?

Just starting out? Need help? Post your questions and find answers here.
vwidmer
Enthusiast
Enthusiast
Posts: 286
Joined: Mon Jan 20, 2014 6:32 pm

Processing events in console?

Post 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
WARNING: I dont know what I am doing! I just put stuff here and there and sometimes like magic it works. So please improve on my code and post your changes so I can learn more. TIA
infratec
Always Here
Always Here
Posts: 7620
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Processing events in console?

Post 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.
infratec
Always Here
Always Here
Posts: 7620
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Processing events in console?

Post 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
infratec
Always Here
Always Here
Posts: 7620
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Processing events in console?

Post 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
Last edited by infratec on Wed Apr 10, 2019 7:50 am, edited 3 times in total.
vwidmer
Enthusiast
Enthusiast
Posts: 286
Joined: Mon Jan 20, 2014 6:32 pm

Re: Processing events in console?

Post by vwidmer »

Thanks that helped alot, thanks for the module as well..
WARNING: I dont know what I am doing! I just put stuff here and there and sometimes like magic it works. So please improve on my code and post your changes so I can learn more. TIA
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: Processing events in console?

Post by davido »

@infratec,
Thank you for posting this example. I found it very instructive. :D
DE AA EB
infratec
Always Here
Always Here
Posts: 7620
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Processing events in console?

Post 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.
Little John
Addict
Addict
Posts: 4791
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Processing events in console?

Post 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.
infratec
Always Here
Always Here
Posts: 7620
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Processing events in console?

Post 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?
Little John
Addict
Addict
Posts: 4791
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Processing events in console?

Post 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.
infratec
Always Here
Always Here
Posts: 7620
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Processing events in console?

Post 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
Post Reply