Page 1 of 2

runtime EditorGadget window not updating with SetGadgetText?

Posted: Sat Oct 03, 2015 9:30 pm
by mqsymth
When the program is running and reading files, the SetGadgetText is not updating my EditorGadget Window

The EditorGadget's ID is #txtWFFile and is defined in Win() routine as
EditorGadget(#txtWFFILE, 90, 310, 380, 25)

In program Run() my code is:

sData = gFileList(R)
sFile = "Working... " + Str(R) + " " + sData
SetActiveGadget(#txtWFFile)
SetGadgetText(#txtWFFile, sFile)

When the code is running the EditorGadget window is not updating with the new sFile. I've done a debug and I can see from the debug output of gFileList(R) that the code is reading in the files one by one but the sFile is not being output to the EditorGadget window

What Am I doing wrong?

Thanks

Re: runtime EditorGadget window not updating with SetGadgetT

Posted: Sat Oct 03, 2015 9:48 pm
by Keya
SetGadgetText with EditorGadget on their own are fine, as a simple skeletal test will show you, so by any chance are you trying to do the SetGadgetText from inside an intensive loop? or perhaps from another thread? and youve confirmed that the sFile variable isnt an empty string? and which operating system(s) are you using?

Re: runtime EditorGadget window not updating with SetGadgetT

Posted: Sat Oct 03, 2015 10:04 pm
by mqsymth
Yes I have confirmed that sFile is not empty by putting a debug sFile directly after sFile.

Yes I am trying to do the SetGadgetText from inside an intensive loop in my Run() Code.

Does that matter? Do I have to pause the loop, run SetGadgetText and then un-pause?

Re: runtime EditorGadget window not updating with SetGadgetT

Posted: Sat Oct 03, 2015 10:17 pm
by Keya
in a single-threaded program where you're going around and around in your 'work loop' sending all these messages to update the text your 'main message loop' isnt receiving them until your work loop finishes. For UI updates you can send custom event messages to your main message loop with PostEvent() and do the updating in that loop, and perhaps using another thread if its suitable
I had to battle this problem myself not too long ago - read through this forum thread for example of using PostEvent from a worker thread to get the main message loop to do UI updates:
http://purebasic.fr/english/viewtopic.p ... =PostEvent
When using threads make sure you dont do UI updates from those or you can get really bad behavior in Linux and Mac especially; use PostEvent to trigger the message loop in your main thread to get it to do UI updates

Re: runtime EditorGadget window not updating with SetGadgetT

Posted: Tue Oct 06, 2015 4:21 pm
by mqsymth
Keya thanks for your help.

I solved the problem another way. I have a Run button on my form.
Case #CB_RUN
RUN()
The run button executes the procedure Run(). Run() puts some values in various editor gadget windows and then creates a thread for the main run by
gThreadID=CreateThread(@xmain(),0)

Where xmain() is all my execution code. Within xmain are are all my SetGadgeText statements for the various EditorGadget windows.

With the thread execution all EditorGadget windows updated during execution. Without the thread but just putting xmain() instead of
CreateThread(@xmain(),0) no EditorGadet windows updated during execution.

I'm converting from PowerBasic to PB to create 64bit EXEs. Unfortunately with the converted code I find PB read files to be very slow when compared to PowerBasic. In reading 20 files of size 600kb with parsing of contents, PB took 19sec and PowerBasic took 4sec with very similar code.

Very disappointing.

Re: runtime EditorGadget window not updating with SetGadgetT

Posted: Tue Oct 06, 2015 4:46 pm
by blueb
mqsymth wrote:I'm converting from PowerBasic to PB to create 64bit EXEs. Unfortunately with the converted code I find PB read files to be very slow when compared to PowerBasic. In reading 20 files of size 600kb with parsing of contents, PB took 19sec and PowerBasic took 4sec with very similar code.

Very disappointing.
I doubt that's actually the case. (I used to use PowerBASIC)

The problem directly converting a end-user program from one language to another
is that your thought process is still PowerBASIC.

You are probably better off starting from scratch, using PureBasic.

Perhaps if you post some source where you think the slowdown is taking place
we could help out. There are many expats on this site. :mrgreen:

blueb

Re: runtime EditorGadget window not updating with SetGadgetT

Posted: Tue Oct 06, 2015 4:53 pm
by Keya
doesnt Powerbasic also create native executables like Purebasic? if thats the case you could look at what it's doing with a debugger and replicate it?

Re: runtime EditorGadget window not updating with SetGadgetT

Posted: Tue Oct 06, 2015 5:32 pm
by mqsymth
blueb wrote:
mqsymth wrote:I'm converting from PowerBasic to PB to create 64bit EXEs. Unfortunately with the converted code I find PB read files to be very slow when compared to PowerBasic. In reading 20 files of size 600kb with parsing of contents, PB took 19sec and PowerBasic took 4sec with very similar code.

Very disappointing.
I doubt that's actually the case. (I used to use PowerBASIC)

The problem directly converting a end-user program from one language to another
is that your thought process is still PowerBASIC.

You are probably better off starting from scratch, using PureBasic.

Perhaps if you post some source where you think the slowdown is taking place
we could help out. There are many expats on this site. :mrgreen:

blueb
Below is my read file converted code. I had to rewrite the Parse and Parsecount code for PB. As I said this read file code takes 19sec to read 20 files and the Powerbasic code takes 4sec.

The reason I switched to PB instead of C++ was it was easier to convert to PB than rewrite all my code for C++

Code: Select all

Procedure.i Parsecount( String$ , delim$ )
  Protected ii.i
  If Right(String$,1)<>delim$
    String$=string$+delim$
  EndIf  
  ii=CountString ( String$ , delim$ )
  ProcedureReturn ii
EndProcedure
;===================================================
Procedure parse(String$,Array sList$(1),delim$)
  Protected ii.i, k.i
  If Right(String$,1)<>delim$
    String$=string$+delim$
  EndIf  
  ii=parsecount (String$, delim$)
  For k = 1 To ii
    sList$(k)=StringField (String$, k, delim$)
  Next
EndProcedure
;=========================================================
 Procedure.i FileExists2(File.s)
  Protected Result
  If FileSize(File) > 0
    Result = #True
  Else
    Result = #False  ; Doesn't exist or a folder
  EndIf
  ProcedureReturn Result
EndProcedure
;========================================================
Procedure ImportMyFiles(myFileName.s, Delimiter.s) 
  Dim lines.s(1)
  Protected i.l, fnum.l, ii.l
  Dim RowValues.s(1)
  Dim lDate.l(1)
  Protected LastLine.l
  Protected sBigString.s
  Protected tempstr.s, sFileSpec.s
  Protected strlen.l, jj.l, NumofCols.l
  Protected dOOSDays.d, dTestDays.d
  Protected myFileSize.q
  ReDim lDate(3) 
    If FileExists2(myFileName)=0  
       MessageRequester( "File Error",myFileName+" does Not Exist")
       ProcedureReturn
    EndIf     
    fnum = 29  
    sBigString=""
;===============================================
;PowerBasic Code    
;    Open myFileName For Binary As #fnum
;    Get$ #fnum,Lof(fnum), BigString
;    Close #fnum
;===============================================    
    If ReadFile(fnum,myFileName)
      myFileSize=Lof(fnum)
      sBigString=ReadString(fnum,#PB_File_IgnoreEOL,myFileSize)
      CloseFile( fnum)
    EndIf    
    Dim lines(ParseCount(sBigString,#LF$))
    LastLine=ParseCount(sBigstring,#LF$)
  ; get all lines in the file
    PARSE (sBigString, lines(), #LF$)
    Dim Rowvalues(50)
    Parse (lines(1),RowValues(),"," )
  ;Setup gCvsArr
    LastLine = ArraySize(lines())
  ;Check If PB put LastLine as nothing 
    If  Len(lines(lastline))=0 : LastLine=LastLine-1 : EndIf
  ;Check For comma on End of Line(1) If so delete it    
    If (Right(lines(1), 1) = ",") 
      lines(1) = Left(lines(1), Len(lines(1)) - 1)
    EndIf ;check For comma on End    
    gCsvCols=ParseCount(lines(1),",")
    gCsvRows=LastLine
    Dim gCsvArr(gCsvRows, gCsvCols)
    For i = 1 To gCsvRows
     ;Check For comma on end.. if so delete it
      If (Right(lines(i), 1) = ",")
            lines(i) = Left(lines(i), Len(lines(i)) - 1)
      EndIf ;check For comma on End
   
      PARSE (lines(i), RowValues(), ",")
      For jj = 1 To gCsvCols
        gCsvArr(i jj) = RowValues(jj)
      Next jj      
    Next i
  sBigString="" ;Release string memory
  FreeArray( lines())
  FreeArray( rowvalues())
EndProcedure

Re: runtime EditorGadget window not updating with SetGadgetT

Posted: Tue Oct 06, 2015 5:36 pm
by mqsymth
Keya wrote:doesnt Powerbasic also create native executables like Purebasic? if thats the case you could look at what it's doing with a debugger and replicate it?
Good idea. PowerBasic uses Windows APIs and ASM code in there functions.

Re: runtime EditorGadget window not updating with SetGadgetT

Posted: Tue Oct 06, 2015 5:51 pm
by Keya
just breakpoint on CreateFile and ReadFile i guess should tell you all you need to know how its reading them? :)
another thing i can think of is that perhaps your Purebasic code is slower because it uses C-style null-terminated strings, so to determine things like their length or use some functions like Right() etc it first has to scan the entire string looking for the null char, so perhaps that's not the most efficient form of string for your needs. Try to break your code down into smaller tests so you can find exactly where the bottlenecks are by comparison :)

Re: runtime EditorGadget window not updating with SetGadgetT

Posted: Tue Oct 06, 2015 9:02 pm
by said
Hi mqsymth,

IMO the reason for slow PB compared to PowerBasic is in the Parse() procedure you are using, using StringField is not fast enough as it has to browse thru the string from the beginning all over again and again ... better use a pointer based procedure something like this one:

Code: Select all

Procedure.i MySplitString(s.s, multiCharSep.s, Array a.s(1))
  ; last substring is not necesseraly followed by a char-sep
  Protected count, i, soc, lnStr,lnBStr, lnSep,lnBSep, ss, ee
  
  soc     = SizeOf(Character)
  lnSep   = Len(multiCharSep) :   lnBSep  = lnSep * soc
  lnStr   = Len(s)            :   lnBStr  = lnStr * soc
  If lnStr <= 0               :   ProcedureReturn 0       : EndIf
  
  count   = CountString(s,multiCharSep)
  If count <= 0
    Dim a(1) : a(1) = s : ProcedureReturn 1
  EndIf
  
  If Right(s,lnSep) <> multiCharSep : count + 1 : EndIf 
  
  Dim a(count) ; a(0) is ignored
  
  i = 1: ss = 0: ee = 0
  While ee < lnBStr
    If CompareMemory(@s + ee, @multiCharSep, lnBSep)
      a(i) = PeekS(@s + ss, (ee-ss)/soc)
      ss = ee + lnBSep: ee = ss: i+1
    Else
      ee + soc
    EndIf
  Wend
  
  If i < count+1: a(count) = PeekS(@s + ss, (ee-ss)/soc) : EndIf
  ProcedureReturn count ;return count of substrings
  
EndProcedure
It splits the string into an array pf sub-strings separated by the param multiCharSep ... If your input files are not that big you can read the whole file in one string using ReadData() and use MySplitString() to first parse the lines and then use it gain to parse each line individually, otherwise you just parse the line being read ... hope this helps. I am sure you will get very close to those 4sec :D

Re: runtime EditorGadget window not updating with SetGadgetT

Posted: Wed Oct 07, 2015 4:55 am
by mqsymth
many thanks said, I'll try it

Re: runtime EditorGadget window not updating with SetGadgetT

Posted: Thu Oct 15, 2015 9:07 pm
by mqsymth
Said: I finally tried your pb Split routine and it reduced the Reading and Parsing of the 20 files to 1.5sec!

Just for the sake of comparison I recoded my routines in C++ with Visual Studio 12. After finding the best C++ parse routine on the web, the same PB code, coded into C++, took 11 sec. It was probably the C++ parse routine that used the c++ substr.

Many thanks!!!!

Re: runtime EditorGadget window not updating with SetGadgetT

Posted: Sun Oct 18, 2015 12:01 am
by said
Glad it was of some help, you are welcome :D

I dont know C++ but may times i had to compare PB to flat C (using gcc) ... and always found PB to be very close :lol: and probably a 100 times easier and funnier to use :D so big thanks to Fred and the team for such a great product

Re: runtime EditorGadget window not updating with SetGadgetT

Posted: Sun Oct 18, 2015 6:12 pm
by mqsymth
Said: A comparison correction. When I compared my PB to my Powerbasic routines, the powerbasic routines did much more in processing the 20 files. i.e sorting 2D arrays, combining ,etc. When I finally coded all the routines into PB, PB took 3.6 sec to complete and Powerbasic took 3.6 seconds to complete. So both were equal in processing speed with the same code.

I can't say this enough but many thanks for your help. Also in getting used to PB, many thanks to Fred for a really great product. While I really loved Powerbasic, I think that PB is a better product, easier to use and debug than Powerbasic. PB found an error in my code that Powerbasic did not.