BindEvent + WaitEvent

Just starting out? Need help? Post your questions and find answers here.
eck49
Enthusiast
Enthusiast
Posts: 153
Joined: Sat Nov 14, 2020 10:08 pm
Location: England

BindEvent + WaitEvent

Post by eck49 »

Is there a way of knowing that a procedure being run is under the umbrella of a BindEvent or BindGadgetEvent?

Some code invoked that way may lead to a situation where I want to give the user information on a fresh window, with its own events, but waiting for these events is not allowed. How can I catch the forbidden situation before it happens, so I can do something else?

The code in question can also be called without going through a BindEvent, when the fresh window is OK.

I suppose I could have my own flag variable, but if PB has a built-in provision, that would be better because less fallible.

I apologise in advance for not responding to replies for the next few days as I will be away from home.
Ubuntu 22.04 64-bit
Purebasic 6.00 (as of 5 Sep 2022)
(native tongue: English)
collectordave
Addict
Addict
Posts: 1309
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: BindEvent + WaitEvent

Post by collectordave »

Just to be clear, a procedure in your main window may create another window to give the user more information in that case speed is obviously not of the essence so why use bind event at all?

If the code is always called from your main loop your main loop can wait for events on the new window as well as the main window.

You will need a procedure to process the events on the new window then use EventWindow()

Repeat

Event = Waitwindowevent()

If EventWindow() = my new window


ProcessNewWindowEvents(Event)


Endif

;You can still process this windows events here


Forever
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
eck49
Enthusiast
Enthusiast
Posts: 153
Joined: Sat Nov 14, 2020 10:08 pm
Location: England

Re: BindEvent + WaitEvent

Post by eck49 »

@collectordave
Your logic makes a lot of sense, and is certainly true of the present project. PB's approach to event handling is more flexible than I am used to and I am still learning - not a fast process at my age!

But where does the time get spent when not using BindEvent? Surely checking for events is a trivial task?

If this is not the case, a program needing the speed of BindEvent handling normally might still want a subsidiary event-generating window for rare events - to gather evidence where there may be a bug, perhaps, and then to offer the user choices. What would you do in such a case?
Ubuntu 22.04 64-bit
Purebasic 6.00 (as of 5 Sep 2022)
(native tongue: English)
collectordave
Addict
Addict
Posts: 1309
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: BindEvent + WaitEvent

Post by collectordave »

Hi

You know the basic

Code: Select all

  Repeat
    
    Event = WaitWindowEvent()
    
    If event = #PB_Event_CloseWindow
      End
    EndIf
    
  ForEver
  
Your application is always locked in this loop.

BindEvent gets the event before this loop and triggers your procedure. The event still ends up here as well.

I use modules.

So where I need another window I programme this inside the module.

Here is a typical one from a help project:-

Code: Select all

DeclareModule NewProject
  
  Declare Open()
  
EndDeclareModule

Module NewProject

IncludeFile "DCTool.pbi"


Global dlgNewProject

Global txtTitle, strTitle, txtPage, cmbPageSize

Global PageName.s,PageWidth.i,PageHeight.i


Procedure CreateProject()
  
  Define HelpDB.i,Criteria.s
  
  ;Create Folders For Project
  CreateDirectory(GetCurrentDirectory() + App::ProjectTitle)
  CreateDirectory(GetCurrentDirectory() + App::ProjectTitle + "\Pages")  
  CreateDirectory(GetCurrentDirectory() + App::ProjectTitle + "\Manual")  
  CreateDirectory(GetCurrentDirectory() + App::ProjectTitle + "\Help") 
  
  ;Copy default Project database
  CopyFile(GetCurrentDirectory() + "Help.db",GetCurrentDirectory() + App::ProjectTitle + #PS$ + App::ProjectTitle +".db")
  
  ;Add Project Detail
  HelpDB = OpenDatabase(#PB_Any,GetCurrentDirectory() + App::ProjectTitle + #PS$ + App::ProjectTitle +".db","","")
  
  Criteria = "INSERT INTO Main (Title,Page,PageHeight,Pagewidth) VALUES('" + App::ProjectTitle + "','" + App::PageName + "'," + Str(app::PageHeight) + "," + Str(App::PageWidth) + ");"
  
  DatabaseUpdate(HelpDB,Criteria)
  
  CloseDatabase(HelpDB)
  
EndProcedure



Procedure Open()
  
  Define Quit.i,Event.i,NPTool.i
  
  
  dlgNewProject = OpenWindow(#PB_Any, 0, 0,380,100, "New Project", #PB_Window_TitleBar | #PB_Window_Tool|#PB_Window_WindowCentered)
  txtTitle = TextGadget(#PB_Any, 10, 50, 200, 20, "Project Title")
  strTitle = StringGadget(#PB_Any, 10, 70, 240, 20, "")
  txtPage = TextGadget(#PB_Any, 270, 50, 100, 20, "Page Size")
  cmbPageSize = ComboBoxGadget(#PB_Any, 270, 70, 90, 20)
  NPTool = IconBarGadget(0, 0, WindowWidth(dlgNewProject),20,#IconBar_Default,dlgNewProject) 
  AddIconBarGadgetItem(NPTool, "Ok", App::imgOk)
  AddIconBarGadgetItem(NPTool, "Cancel", App::imgExit)  
  ResizeIconBarGadget(NPTool, #PB_Ignore, #IconBar_Auto)  
  SetIconBarGadgetColor(NPTool, 1, RGB(176,224,230))
  
  
  AddGadgetItem(cmbPageSize, -1, "A4")
  AddGadgetItem(cmbPageSize, -1, "Letter")
  SetGadgetState(cmbPageSize,0)
  App::PageHeight = 297
  App::PageWidth = 210
  App::PageName = "A4"
  
  
  
  
  
  StickyWindow(dlgNewProject,#True)
  
  Repeat
      
      Event = WaitWindowEvent()
      Select Event
        Case #PB_Event_CloseWindow
          CloseWindow(dlgNewProject)
          Quit = #True
          
  
      Case #PB_Event_Menu
        Select EventMenu()
        EndSelect
  
      Case #PB_Event_Gadget
        Select EventGadget()
            
          Case NPTool
            
            Select EventData()
                
              Case 0    ;Create New
                
                If Trim(GetGadgetText(strTitle)) > ""
                  App::ProjectTitle = Trim(GetGadgetText(strTitle))
                  CreateProject()
                  CloseWindow(dlgNewProject)
                  Quit = #True
                Else
                  ;No title
                EndIf
                
              Case 1    ;Cancel
                CloseWindow(dlgNewProject)
                Quit = #True  
                
            EndSelect   
            
          Case cmbPageSize
            
            If GetGadgetText(cmbPageSize) = "A4"
              App::PageHeight = 297
              App::PageWidth = 210
              App::PageName = "A4"
            Else
              App::PageHeight = 297
              App::PageWidth = 210             
              App::PageName = "Letter"
            EndIf
 
        EndSelect
    EndSelect
    
  Until Quit = #True

  EndProcedure
  
  EndModule
  
You can see here I have incorporated an event loop in the open procedure.

This is because I know that nothing else should be happening when the user starts a new project. This loop takes over from the main loop.

this would be called from the main Loop like this


NewProject::Open()

The main loop is still where my programme is but it cannot get back from NewProject::Open() until that is finished. After which it carries on as normal.

If you need the second window open and have the first window still active you create a procedure out of the event loop in the module and call it something like MyWindowEvents(Event.i)

Then in the main loop you would check:-

Code: Select all

  Repeat
    
    Event = WaitWindowEvent()
    
    If EventWindow() = NewProject::MyNewWindow ;Declare MyNewWindow as Global in the module header
    
      NewProject::MyWindowEvents(Event)
      
    endif

    If event = #PB_Event_CloseWindow
      End
    EndIf
    
  ForEver
   
Once you have the idea you can build what you wish.

So where not so much a bug but where your programme hits a problem you can have a separate module to handle your problems which can have a window or do stuff to try and correct what is wrong, mostly just to close down as safely as possible.

This is what I do. I also have a separate module for displaying my help files etc.

Always remember it is the programmer that must ensure the Events are always checked so you must always have an active event loop.

If you use modules you can have one main file and all other windows as included files, but only one event loop per file until you get used to it.

Much easier as just one single loop in a large application can occupy thousands of lines.

Clear as mud?
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
eck49
Enthusiast
Enthusiast
Posts: 153
Joined: Sat Nov 14, 2020 10:08 pm
Location: England

Re: BindEvent + WaitEvent

Post by eck49 »

@collectordave
Actually, I found that very clear and helpful. The kind of thing which could usefully go in a reference book. Not muddy at all.

Unlike a local field, under which is the water main supplying 50 thousand people. The pipe burst this morning and most folk were without water for several hours, local schools closed, some businesses etc. We are one of the few still having a cold water tank, so were not affected. The same main burst in the same field in 2017....

Thank you
Ubuntu 22.04 64-bit
Purebasic 6.00 (as of 5 Sep 2022)
(native tongue: English)
Post Reply