Page 4 of 4

Re: If i had 1000 € to offer for a PB feature...

Posted: Mon Jul 30, 2012 8:23 am
by TI-994A
Tenaja wrote:... To sum it up, PB is so fast and simple for most projects that it gets very frustrating when you want to do advanced tasks. (Especially when those tasks are not documented...)
Advanced programming is always frustrating, and often not well documented, in any language for that matter. But more importantly, it is still possible with PureBasic. (pardon my zeal)

Re: If i had 1000 € to offer for a PB feature...

Posted: Mon Jul 30, 2012 11:12 am
by electrochrisso
TI-994A wrote:
Tenaja wrote:... To sum it up, PB is so fast and simple for most projects that it gets very frustrating when you want to do advanced tasks. (Especially when those tasks are not documented...)
Advanced programming is always frustrating, and often not well documented, in any language for that matter. But more importantly, it is still possible with PureBasic. (pardon my zeal)
You are right on there TI-994A, Just about anything would be possible with PB, one just need to know how to do it. :wink:
Besides if the PB team had to spend the time on advanced documentation, they would never get time to develop PB.

Re: If i had 1000 € to offer for a PB feature...

Posted: Tue Jul 31, 2012 3:24 pm
by fromVB
electrochrisso wrote:
TI-994A wrote:
Tenaja wrote:... To sum it up, PB is so fast and simple for most projects that it gets very frustrating when you want to do advanced tasks. (Especially when those tasks are not documented...)
Advanced programming is always frustrating, and often not well documented, in any language for that matter. But more importantly, it is still possible with PureBasic. (pardon my zeal)
You are right on there TI-994A, Just about anything would be possible with PB, one just need to know how to do it. :wink:
Besides if the PB team had to spend the time on advanced documentation, they would never get time to develop PB.
In another forum post "optimize code size" I get the feeling that PB translates inefficiently. Are programs written with PB slow?

Re: If i had 1000 € to offer for a PB feature...

Posted: Tue Jul 31, 2012 3:52 pm
by IdeasVacuum
In another forum post "optimize code size" I get the feeling that PB translates inefficiently. Are programs written with PB slow?
That's a 'how long is a piece of string' type question really, but I'll stick my neck out and say that generally apps built with PB are not slow. If the definition of slow is an app written in C#, then the same app written in PB is fast.

Re: If i had 1000 € to offer for a PB feature...

Posted: Tue Jul 31, 2012 4:24 pm
by Shield
Except PB usually doesn't stand a chance in everyday cases against .NET. :wink:

Re: If i had 1000 € to offer for a PB feature...

Posted: Tue Jul 31, 2012 4:53 pm
by Danilo
fromVB wrote:Are programs written with PB slow?
It is not so slow at all, because we have very fast machines today. It is just that high-end compilers
generate much more optimized, faster code.
For general everyday work, it is fast enough most of the time. The inefficiencies add up if you call something
many million times (a second), for example when calculating image pixels in real time. In this case you have
to inline (avoid PB procedure calls) and optimize yourself. With ASM if you can.

PB compared to other BASIC compilers should be pretty OK. Compared to high-end compilers of big companies,
it is usually not as efficient. Just try it for some time, should be OK if you come from VB6. ;)

Re: If i had 1000 € to offer for a PB feature...

Posted: Tue Jul 31, 2012 6:17 pm
by Tenaja
fromVB wrote:In another forum post "optimize code size" I get the feeling that PB translates inefficiently. Are programs written with PB slow?
PB is great for beginners. It is great for cross-platform programs.

PB uses C-compiled libraries, so the libraries are pretty good (likely as good as "anything"), but the output of the manual code is pretty rudimentary (i.e. not optimized). If speed is your primary concern, and you are planning massive CPU-intensive calculations (and KNOW what that means) then PB is not the best choice.

If you are doing a gui, then speed is no concern whatsoever--there will be no noticeable delays, and you will be waiting for an input almost the entire time.

PB is faster than some basics. It is especially faster than any interpreted basic.
Java is compiled on the fly, so it takes a bit longer to get started, but then it is likely faster after the fact. (It even beats C in some benchmarks!)
C is faster than anything, overall. (The exception being specific benchmarks in Java.)

Most likely, vb is faster than PB. VB has had decades of optimizations performed. With PB, there have not been any optimizations since a peephole optimizer was added to 64-bit versions in 2009. Recent suggestions for optimization have been declined with the claim (paraphrasing) "it doesn't matter."

The bottom line is that PB gives you the option to make both good and bad code. The rest is up to you. I chose it because it seemed the best option for cross platform work, if you have an aversion to C.

--an aside-- the Java-written Open Office is so pathetically slow with a million values in a spreadsheet that it took nearly an hour to process a simple graph. In MS Excel, it was nearly instantaneous. There is NO WAY that C is that much faster than Java in ANY benchmark test... the Java implementation either has poor memory management, or poor coding. PB doesn't have bad memory management, but the poor coding is up to you to remove. Maybe the Java implementation tried to update the GUI with every calculation, rather than batch it and update at the end.

Re: If i had 1000 € to offer for a PB feature...

Posted: Wed Aug 01, 2012 11:47 pm
by luis
Probably (I'm a little torn between some different things) the biggest limitation FOR ME that I didn't see mentioned here is the constant clashing of definitions (var names, procedures names, constants) you have to face when you start to build something large or you integrate together various piece of code from different sources.

The fact you need to constantly plan ahead and use unique prefix (this is from my graph lib, all procedures and constants are prefixed with GRAPH_ !), underscores (this is internal use only, you understand that from the underscore!), and similar things to keep various piece of code to fight against each other or to be too much visible when they shouldn't put a dent in the overall experience.

Some kind of modules or namespaces implementation would be really useful to everyone not writing single, closed, self-sufficient programs every single time (but I understand is not a small task).

Re: If i had 1000 € to offer for a PB feature...

Posted: Fri Aug 03, 2012 1:32 am
by BorisTheOld
luis wrote: ......the biggest limitation FOR ME that I didn't see mentioned here is the constant clashing of definitions (var names, procedures names, constants) you have to face when you start to build something large or you integrate together various piece of code from different sources.

The fact you need to constantly plan ahead and use unique prefix.....
Since switching to PB two years ago, we've put a lot of effort into planning ahead. As a result, we've put together about 100 macros that allow us to hide all the messy stuff that might cause problems in our code. Such as remembering when to use special characters like @ ? and *.

We've also set up all our modules and programs as classes, using a psuedo-OOP structure. The macros allow us to create code that is self documenting and that hides the details of procedure and variable names. This results in code that is not cluttered with "housekeeping" information.

Each class consists of two Include files - one for the interface and one for the methods. We need two separate files because PB is a single pass compiler. All the interfaces need to be defined before any of the class methods.

Later this year we hope to have all this documented on our web site.

Here's a simple example of an Interface:

Code: Select all

;===============================================
;
;  File181 Class Interface  :  Package Menu Items
;
;===============================================
;
;  strRecord181
;
Structure strRecord181
  Field(nPackageKey, typDword)                                                           ; 14453 : package number (key)
  Field(nPackageMenuKey, typDword)                                                       ; 14457 : package menu number (key)
  Field(nMenuItemKey, typDword)                                                          ; 14458 : package menu item (key)
  Field(cMenuItemType, typChar)                                                          ; 11689 : P=program  S=separator  X=exit
  Field(nProgramNumber, typDword)                                                        ; 11690 : program number:  2000 - 2999
  Field(sMenuItemText, typString)                                                        ; 11691 : menu item text
  Field(cHotkeyChar, typChar)                                                            ; 11683 : hot key character: alphanumeric
  Field(nHotkeyPosition, typDword)                                                       ; 11677 : hot key position in text
  Field(cStateStartFlag, typChar)                                                        ; 12307 : menu state during sign-on
  Field(cStateNormalFlag, typChar)                                                       ; 12308 : menu state during normal ops
  Field(cStateCrashFlag, typChar)                                                        ; 12309 : menu state during crash recovery
  Field(cStateInstallFlag, typChar)                                                      ; 14343 : menu state during install
  Field(sNotUsed062, typString)                                                          ; 10024 :
EndStructure
;
;===============================================
;
;  Interface
;
DeclareExternalFunction(File181, Create, typObject) ()
;
Interface objFile181
  Func(Destroy, typObject) ()
  Func(Clone,   typObject) ()
  Subr(Open)      (ByRef(bruHcb, udtIsamHcb), ByVal(bvsPackageCode, typString), ByVal(bvdDateToday, typDate), ByVal(bvnBatch, typDword))
  Subr(Close)     (ByRef(bruHcb, udtIsamHcb))
  Subr(EqualHigh) (ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181), ByVal(bviIndex, typInt32), ByVal(bviPartKeyParm, typInt32))
  Subr(LowEqual)  (ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181), ByVal(bviIndex, typInt32), ByVal(bviPartKeyParm, typInt32))
  Subr(Read)      (ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181), ByVal(bviIndex, typInt32))
  Subr(Next)      (ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181), ByVal(bviIndex, typInt32), ByVal(bviPartKeyParm, typInt32))
  Subr(Previous)  (ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181), ByVal(bviIndex, typInt32), ByVal(bviPartKeyParm, typInt32))
  Subr(Add)       (ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181))
  Subr(Update)    (ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181))
  Subr(Delete)    (ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181))
  Subr(First)     (ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181), ByVal(bviIndex, typInt32), ByVal(bviPartKeyParm, typInt32))
  Subr(Last)      (ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181), ByVal(bviIndex, typInt32), ByVal(bviPartKeyParm, typInt32))
  Subr(Empty)     (ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181))
  Subr(Find)      (ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181), ByVal(bviIndex, typInt32), ByVal(bviPartKeyParm, typInt32))
  Subr(Write)     (ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181))
EndInterface
;
;===============================================
;  end of  :  File181 Class Interface
;===============================================
And here's the associated Class:

Code: Select all

;===============================================
;
;  File181 Class Methods                         Package Menu Items
;
;===============================================
;
;  Properties
;
Structure strFile181
  FieldPointer(prpVirtualTable)                                                          ; 16393 : pointer to the class virtual table
  Field(priReferenceCount, typInt32)                                                     ; 16394 : class reference count
  Field(proDvsam, objDvsam)                                                              ; 16395 : instance of the Dvsam class
EndStructure
;
;===============================================
;
;  Declares
;
DeclarePrivateSubroutine(File181, GetRecord) (ByVal(Me, strFile181), ByRef(brrRecord, strRecord181))
DeclarePrivateSubroutine(File181, PutRecord) (ByVal(Me, strFile181), ByRef(brrRecord, strRecord181))
;
;===============================================
;
ExternalFunction(File181, Create, typObject) ()
;
;  Create                                        create a class instance
;
  Local(Me, strFile181)

  Me = AllocateMemory(SizeOf(strFile181))
  If IsObject(Me)
    InitializeStructure(Me, strFile181)
    Me\prpVirtualTable   = LabelPtr(File181, VirtualTable)
    Me\priReferenceCount = 1
    Me\proDvsam          = CreateObject(Dvsam)
  EndIf
  ProcedureReturn Me
EndFunction
;
;===============================================
;
ExternalFunction(File181, Destroy, typObject) (ByVal(Me, strFile181))
;
;  Destroy                                       destroy a class instance
;
  If IsObject(Me)
    If Me\priReferenceCount > 1
      Me\priReferenceCount = Me\priReferenceCount - 1
    Else
      Me\proDvsam = ReturnObject(Me\proDvsam, Destroy) ()
      ClearStructure(Me, strFile181)
      FreeMemory(Me)
    EndIf
  EndIf
  ProcedureReturn 0
EndFunction
;
;===============================================
;
ExternalFunction(File181, Clone, typObject) (ByVal(Me, strFile181))
;
;  Clone                                         clone a class instance
;
  If IsObject(Me)
    Me\priReferenceCount = Me\priReferenceCount + 1
  EndIf
  ProcedureReturn Me
EndFunction
;
;===============================================
;
ExternalSubroutine(File181, Open) (ByVal(Me, strFile181), ByRef(bruHcb, udtIsamHcb), ByVal(bvsPackageCode, typString), ByVal(bvdDateToday, typDate), ByVal(bvnBatch, typDword))
;
;  Open                                          start file operations
;
;  bruHcb                                        14869 : isam file handle control block
;  bvsPackageCode                                10001 : package code
;  bvdDateToday                                  12312 : effective sign-on date
;  bvnBatch                                      10305 : file batch number
;
;--} local data

  Local(sPackageCode, typString)                                                         ; 10001 : package code
  Local(sUniqueName, typString)                                                          ; 11236 : unique part of dos file name
  Local(sFileExtension, typString)                                                       ; 14843 : dos file extension
  Local(sStringValue, typString)                                                         ; 14890 : generic string value
  Local(sDosFileName, typString)                                                         ; 14704 : dos file name:  xxaaaaaa.nnn
  Local(sFilePath, typString)                                                            ; 15040 : generic file path

;--} local code

  sPackageCode   = "DD"
  sUniqueName    = "MENITM"
  sFileExtension = "181"

  sDosFileName = sPackageCode + sUniqueName + #cCHAR_PERIOD + sFileExtension             ; create file name
  sFilePath    = ReturnObject(Me\proDvsam, GetPath) (sDosFileName)                       ; create file path

  CallObject(Me\proDvsam, DefineFile) (Ref(bruHcb), 181, "Package Menu Items", sFilePath, 120, 13, 1)

  CallObject(Me\proDvsam, DefineField) (Ref(bruHcb), 1, #vFIELD_DWORD, 0, 6)             ; 14453 : package number (key)
  CallObject(Me\proDvsam, DefineField) (Ref(bruHcb), 2, #vFIELD_DWORD, 6, 3)             ; 14457 : package menu number (key)
  CallObject(Me\proDvsam, DefineField) (Ref(bruHcb), 3, #vFIELD_DWORD, 9, 3)             ; 14458 : package menu item (key)
  CallObject(Me\proDvsam, DefineField) (Ref(bruHcb), 4, #vFIELD_CHAR, 12, 1)             ; 11689 : P=program  S=separator  X=exit
  CallObject(Me\proDvsam, DefineField) (Ref(bruHcb), 5, #vFIELD_DWORD, 13, 6)            ; 11690 : program number:  2000 - 2999
  CallObject(Me\proDvsam, DefineField) (Ref(bruHcb), 6, #vFIELD_STRING, 19, 32)          ; 11691 : menu item text
  CallObject(Me\proDvsam, DefineField) (Ref(bruHcb), 7, #vFIELD_CHAR, 51, 1)             ; 11683 : hot key character: alphanumeric
  CallObject(Me\proDvsam, DefineField) (Ref(bruHcb), 8, #vFIELD_DWORD, 52, 2)            ; 11677 : hot key position in text
  CallObject(Me\proDvsam, DefineField) (Ref(bruHcb), 9, #vFIELD_CHAR, 54, 1)             ; 12307 : menu state during sign-on
  CallObject(Me\proDvsam, DefineField) (Ref(bruHcb), 10, #vFIELD_CHAR, 55, 1)            ; 12308 : menu state during normal ops
  CallObject(Me\proDvsam, DefineField) (Ref(bruHcb), 11, #vFIELD_CHAR, 56, 1)            ; 12309 : menu state during crash recovery
  CallObject(Me\proDvsam, DefineField) (Ref(bruHcb), 12, #vFIELD_CHAR, 57, 1)            ; 14343 : menu state during install
  CallObject(Me\proDvsam, DefineField) (Ref(bruHcb), 13, #vFIELD_STRING, 58, 62)         ; 10024 :

  CallObject(Me\proDvsam, DefineIndex) (Ref(bruHcb), 1, 1, 2, 3, 0, 0, 0, 0, 0)

  CallObject(Me\proDvsam, DefineUserFlag) (Ref(bruHcb), 1, "N")                          ; 11242 : Y = file is a report file
  CallObject(Me\proDvsam, DefineUserFlag) (Ref(bruHcb), 2, "N")                          ; 11243 : Y = generate a conversion pgm
  CallObject(Me\proDvsam, DefineUserFlag) (Ref(bruHcb), 3, "N")                          ; 11244 : Y = use date in file name
  CallObject(Me\proDvsam, DefineUserFlag) (Ref(bruHcb), 4, "N")                          ; 11245 : N=normal, S=station, B=batch
  CallObject(Me\proDvsam, DefineUserFlag) (Ref(bruHcb), 5, "E")                          ; 11246 : entity status: E=enter, C=code, T=test, D=doc, R=release, X=obs
  CallObject(Me\proDvsam, DefineUserFlag) (Ref(bruHcb), 6, "C")                          ; 11247 : C=cobol, B=basic, P=pascal
  CallObject(Me\proDvsam, DefineUserFlag) (Ref(bruHcb), 7, "N")                          ; 11248 : Y = allow pkg code override

  CallObject(Me\proDvsam, OpenFile) (Ref(bruHcb))                                        ; open file: 181 - Package Menu Items

EndSubroutine
;
;===============================================
;
ExternalSubroutine(File181, Close) (ByVal(Me, strFile181), ByRef(bruHcb, udtIsamHcb))
;
;  Close                                         stop file operations
;
;  bruHcb                                        14869 : isam file handle control block
;

  CallObject(Me\proDvsam, CloseFile) (Ref(bruHcb))                                       ; close file

EndSubroutine
;
;===============================================
;
ExternalSubroutine(File181, EqualHigh) (ByVal(Me, strFile181), ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181), ByVal(bviIndex, typInt32), ByVal(bviPartKeyParm, typInt32))
;
;  EqualHigh                                     read equal or high (next) record
;
;  bruHcb                                        14869 : isam file handle control block
;  brrRecord                                     14708 : user data record
;  bviIndex                                      12061 : generic index number
;  bviPartKeyParm                                14906 : partial key:  from parm
;

  CallClass(File181, PutRecord) (Me, Ref(brrRecord))                                     ; put record in i/o buffer
  CallObject(Me\proDvsam, EqualHighRecord) (Ref(bruHcb), bviIndex, bviPartKeyParm)       ; retrieve record
  If Ref(bruHcb)\iReturn = #iRETURN_OK
    CallClass(File181, GetRecord) (Me, Ref(brrRecord))                                   ; move i/o buffer to record
  EndIf

EndSubroutine
;
;===============================================
;
ExternalSubroutine(File181, LowEqual) (ByVal(Me, strFile181), ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181), ByVal(bviIndex, typInt32), ByVal(bviPartKeyParm, typInt32))
;
;  LowEqual                                      read low (previous) or equal record
;
;  bruHcb                                        14869 : isam file handle control block
;  brrRecord                                     14708 : user data record
;  bviIndex                                      12061 : generic index number
;  bviPartKeyParm                                14906 : partial key:  from parm
;

  CallClass(File181, PutRecord) (Me, Ref(brrRecord))                                     ; put record in i/o buffer
  CallObject(Me\proDvsam, LowEqualRecord) (Ref(bruHcb), bviIndex, bviPartKeyParm)        ; retrieve record
  If Ref(bruHcb)\iReturn = #iRETURN_OK
    CallClass(File181, GetRecord) (Me, Ref(brrRecord))                                   ; move i/o buffer to record
  EndIf

EndSubroutine
;
;===============================================
;
ExternalSubroutine(File181, Read) (ByVal(Me, strFile181), ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181), ByVal(bviIndex, typInt32))
;
;  Read                                          read a specific record
;
;  bruHcb                                        14869 : isam file handle control block
;  brrRecord                                     14708 : user data record
;  bviIndex                                      12061 : generic index number
;

  CallClass(File181, PutRecord) (Me, Ref(brrRecord))                                     ; put record in i/o buffer
  CallObject(Me\proDvsam, ReadRecord) (Ref(bruHcb), bviIndex)                            ; retrieve record
  If Ref(bruHcb)\iReturn = #iRETURN_OK
    CallClass(File181, GetRecord) (Me, Ref(brrRecord))                                   ; move i/o buffer to record
  EndIf

EndSubroutine
;
;===============================================
;
ExternalSubroutine(File181, Next) (ByVal(Me, strFile181), ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181), ByVal(bviIndex, typInt32), ByVal(bviPartKeyParm, typInt32))
;
;  Next                                          read the next record
;
;  bruHcb                                        14869 : isam file handle control block
;  brrRecord                                     14708 : user data record
;  bviIndex                                      12061 : generic index number
;  bviPartKeyParm                                14906 : partial key:  from parm
;

  CallClass(File181, PutRecord) (Me, Ref(brrRecord))                                     ; put record in i/o buffer
  CallObject(Me\proDvsam, NextRecord) (Ref(bruHcb), bviIndex, bviPartKeyParm)            ; retrieve next record
  If Ref(bruHcb)\iReturn = #iRETURN_OK
    CallClass(File181, GetRecord) (Me, Ref(brrRecord))                                   ; move i/o buffer to record
  EndIf

EndSubroutine
;
;===============================================
;
ExternalSubroutine(File181, Previous) (ByVal(Me, strFile181), ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181), ByVal(bviIndex, typInt32), ByVal(bviPartKeyParm, typInt32))
;
;  Previous                                      read the previous record
;
;  bruHcb                                        14869 : isam file handle control block
;  brrRecord                                     14708 : user data record
;  bviIndex                                      12061 : generic index number
;  bviPartKeyParm                                14906 : partial key:  from parm
;

  CallClass(File181, PutRecord) (Me, Ref(brrRecord))                                     ; put record in i/o buffer
  CallObject(Me\proDvsam, PreviousRecord) (Ref(bruHcb), bviIndex, bviPartKeyParm)        ; retrieve previous record
  If Ref(bruHcb)\iReturn = #iRETURN_OK
    CallClass(File181, GetRecord) (Me, Ref(brrRecord))                                   ; move i/o buffer to record
  EndIf

EndSubroutine
;
;===============================================
;
ExternalSubroutine(File181, Add) (ByVal(Me, strFile181), ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181))
;
;  Add                                           add a new record
;
;  bruHcb                                        14869 : isam file handle control block
;  brrRecord                                     14708 : user data record
;

  CallClass(File181, PutRecord) (Me, Ref(brrRecord))                                     ; put record in i/o buffer
  CallObject(Me\proDvsam, AddRecord) (Ref(bruHcb))                                       ; add record

EndSubroutine
;
;===============================================
;
ExternalSubroutine(File181, Update) (ByVal(Me, strFile181), ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181))
;
;  Update                                        update an existing record
;
;  bruHcb                                        14869 : isam file handle control block
;  brrRecord                                     14708 : user data record
;

  CallClass(File181, PutRecord) (Me, Ref(brrRecord))                                     ; put record in i/o buffer
  CallObject(Me\proDvsam, UpdateRecord) (Ref(bruHcb))                                    ; update record

EndSubroutine
;
;===============================================
;
ExternalSubroutine(File181, Delete) (ByVal(Me, strFile181), ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181))
;
;  Delete                                        delete a record
;
;  bruHcb                                        14869 : isam file handle control block
;  brrRecord                                     14708 : user data record
;

  CallClass(File181, PutRecord) (Me, Ref(brrRecord))                                     ; put record in i/o buffer
  CallObject(Me\proDvsam, DeleteRecord) (Ref(bruHcb))                                    ; delete record

EndSubroutine
;
;===============================================
;
ExternalSubroutine(File181, First) (ByVal(Me, strFile181), ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181), ByVal(bviIndex, typInt32), ByVal(bviPartKeyParm, typInt32))
;
;  First                                         read the first record
;
;  bruHcb                                        14869 : isam file handle control block
;  brrRecord                                     14708 : user data record
;  bviIndex                                      12061 : generic index number
;  bviPartKeyParm                                14906 : partial key:  from parm
;

  CallClass(File181, PutRecord) (Me, Ref(brrRecord))                                     ; put record in i/o buffer
  CallObject(Me\proDvsam, FirstRecord) (Ref(bruHcb), bviIndex, bviPartKeyParm)           ; retrieve first record
  If Ref(bruHcb)\iReturn = #iRETURN_OK
    CallClass(File181, GetRecord) (Me, Ref(brrRecord))                                   ; move i/o buffer to record
  EndIf

EndSubroutine
;
;===============================================
;
ExternalSubroutine(File181, Last) (ByVal(Me, strFile181), ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181), ByVal(bviIndex, typInt32), ByVal(bviPartKeyParm, typInt32))
;
;  Last                                          read the last record
;
;  bruHcb                                        14869 : isam file handle control block
;  brrRecord                                     14708 : user data record
;  bviIndex                                      12061 : generic index number
;  bviPartKeyParm                                14906 : partial key:  from parm
;

  CallClass(File181, PutRecord) (Me, Ref(brrRecord))                                     ; put record in i/o buffer
  CallObject(Me\proDvsam, LastRecord) (Ref(bruHcb), bviIndex, bviPartKeyParm)            ; retrieve last record
  If Ref(bruHcb)\iReturn = #iRETURN_OK
    CallClass(File181, GetRecord) (Me, Ref(brrRecord))                                   ; move i/o buffer to record
  EndIf

EndSubroutine
;
;===============================================
;
ExternalSubroutine(File181, Empty) (ByVal(Me, strFile181), ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181))
;
;  Empty                                         build an empty record
;
;  bruHcb                                        14869 : isam file handle control block
;  brrRecord                                     14708 : user data record
;

  CallObject(Me\proDvsam, EmptyRecord) (Ref(bruHcb))                                     ; retrieve empty record
  CallClass(File181, GetRecord) (Me, Ref(brrRecord))                                     ; move i/o buffer to record

EndSubroutine
;
;===============================================
;
ExternalSubroutine(File181, Find) (ByVal(Me, strFile181), ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181), ByVal(bviIndex, typInt32), ByVal(bviPartKeyParm, typInt32))
;
;  Find                                          find an equal or greater record
;
;  bruHcb                                        14869 : isam file handle control block
;  brrRecord                                     14708 : user data record
;  bviIndex                                      12061 : generic index number
;  bviPartKeyParm                                14906 : partial key:  from parm
;

  CallClass(File181, PutRecord) (Me, Ref(brrRecord))                                     ; put record in i/o buffer
  CallObject(Me\proDvsam, FindRecord) (Ref(bruHcb), bviIndex, bviPartKeyParm)            ; find record
  If Ref(bruHcb)\iReturn <> #iRETURN_KEY_NOT_FOUND
    CallClass(File181, GetRecord) (Me, Ref(brrRecord))                                   ; move i/o buffer to record
  EndIf

EndSubroutine
;
;===============================================
;
ExternalSubroutine(File181, Write) (ByVal(Me, strFile181), ByRef(bruHcb, udtIsamHcb), ByRef(brrRecord, strRecord181))
;
;  Write                                         write (add or update) a record
;
;  bruHcb                                        14869 : isam file handle control block
;  brrRecord                                     14708 : user data record
;

  CallClass(File181, PutRecord) (Me, Ref(brrRecord))                                     ; put record in i/o buffer
  CallObject(Me\proDvsam, WriteRecord) (Ref(bruHcb))                                     ; update or add a record

EndSubroutine
;
;===============================================
;
PrivateSubroutine(File181, GetRecord) (ByVal(Me, strFile181), ByRef(brrRecord, strRecord181))
;
;  GetRecord                                     get the record data
;
;  brrRecord                                     14708 : user data record
;

  Ref(brrRecord)\nPackageKey = ReturnObject(Me\proDvsam, GetDword) (1, 6)
  Ref(brrRecord)\nPackageMenuKey = ReturnObject(Me\proDvsam, GetDword) (7, 3)
  Ref(brrRecord)\nMenuItemKey = ReturnObject(Me\proDvsam, GetDword) (10, 3)
  Ref(brrRecord)\cMenuItemType = ReturnObject(Me\proDvsam, GetChar) (13)
  Ref(brrRecord)\nProgramNumber = ReturnObject(Me\proDvsam, GetDword) (14, 6)
  Ref(brrRecord)\sMenuItemText = ReturnObject(Me\proDvsam, GetString) (20, 32)
  Ref(brrRecord)\cHotkeyChar = ReturnObject(Me\proDvsam, GetChar) (52)
  Ref(brrRecord)\nHotkeyPosition = ReturnObject(Me\proDvsam, GetDword) (53, 2)
  Ref(brrRecord)\cStateStartFlag = ReturnObject(Me\proDvsam, GetChar) (55)
  Ref(brrRecord)\cStateNormalFlag = ReturnObject(Me\proDvsam, GetChar) (56)
  Ref(brrRecord)\cStateCrashFlag = ReturnObject(Me\proDvsam, GetChar) (57)
  Ref(brrRecord)\cStateInstallFlag = ReturnObject(Me\proDvsam, GetChar) (58)
  Ref(brrRecord)\sNotUsed062 = ReturnObject(Me\proDvsam, GetString) (59, 62)

EndSubroutine
;
;===============================================
;
PrivateSubroutine(File181, PutRecord) (ByVal(Me, strFile181), ByRef(brrRecord, strRecord181))
;
;  PutRecord                                     put the record data
;
;  brrRecord                                     14708 : user data record
;

  CallObject(Me\proDvsam, PutDword) (Ref(brrRecord)\nPackageKey, 1, 6)
  CallObject(Me\proDvsam, PutDword) (Ref(brrRecord)\nPackageMenuKey, 7, 3)
  CallObject(Me\proDvsam, PutDword) (Ref(brrRecord)\nMenuItemKey, 10, 3)
  CallObject(Me\proDvsam, PutChar) (Ref(brrRecord)\cMenuItemType, 13)
  CallObject(Me\proDvsam, PutDword) (Ref(brrRecord)\nProgramNumber, 14, 6)
  CallObject(Me\proDvsam, PutString) (Ref(brrRecord)\sMenuItemText, 20, 32)
  CallObject(Me\proDvsam, PutChar) (Ref(brrRecord)\cHotkeyChar, 52)
  CallObject(Me\proDvsam, PutDword) (Ref(brrRecord)\nHotkeyPosition, 53, 2)
  CallObject(Me\proDvsam, PutChar) (Ref(brrRecord)\cStateStartFlag, 55)
  CallObject(Me\proDvsam, PutChar) (Ref(brrRecord)\cStateNormalFlag, 56)
  CallObject(Me\proDvsam, PutChar) (Ref(brrRecord)\cStateCrashFlag, 57)
  CallObject(Me\proDvsam, PutChar) (Ref(brrRecord)\cStateInstallFlag, 58)
  CallObject(Me\proDvsam, PutString) (Ref(brrRecord)\sNotUsed062, 59, 62)

EndSubroutine
;
;===============================================
;
;  Virtual Table
;
DataSection
  Label(File181, VirtualTable)
  InterfaceFunction   (File181, Destroy)
  InterfaceFunction   (File181, Clone)
  InterfaceSubroutine (File181, Open)
  InterfaceSubroutine (File181, Close)
  InterfaceSubroutine (File181, EqualHigh)
  InterfaceSubroutine (File181, LowEqual)
  InterfaceSubroutine (File181, Read)
  InterfaceSubroutine (File181, Next)
  InterfaceSubroutine (File181, Previous)
  InterfaceSubroutine (File181, Add)
  InterfaceSubroutine (File181, Update)
  InterfaceSubroutine (File181, Delete)
  InterfaceSubroutine (File181, First)
  InterfaceSubroutine (File181, Last)
  InterfaceSubroutine (File181, Empty)
  InterfaceSubroutine (File181, Find)
  InterfaceSubroutine (File181, Write)
EndDataSection
;
;===============================================
;  end of  :  File181 Class Methods
;===============================================

Re: If i had 1000 € to offer for a PB feature...

Posted: Fri Aug 03, 2012 8:22 am
by endo
That's a very good work BorisTheOld, could you share the link to your web site please? If there are stuff about PureBasic.

Re: If i had 1000 € to offer for a PB feature...

Posted: Fri Aug 03, 2012 4:40 pm
by BorisTheOld
Our web site is down for a few months while we redesign it. We no longer need a sales oriented site, so I've decided to change its focus.

I've been programming for 50 years, so I figured it might benefit other programmers if I described some of the techniques I've used over the years. And since we're now using PB for all our work, it seemed like a good idea to show how, and why, we're using these techniques with PB.

Stay tuned!

And by the way, here's how some of the statements in the above code translate to real PB statements. Not too different, but a lot easier to read and understand.

We use our own Data Dictionary software for generating all our code. So here's the original machine-generated code:

Code: Select all

;===============================================
;
;  File181 Class Methods                         Package Menu Items
;
;===============================================
;
;  Properties
;
Structure strFile181
  FieldPointer(prpVirtualTable)
  Field(priReferenceCount, typInt32)
  Field(proDvsam, objDvsam)
EndStructure
;
;===============================================
;
;  Declares
;
DeclarePrivateSubroutine(File181, GetRecord) (ByVal(Me, strFile181), ByRef(brrRecord, strRecord181))
DeclarePrivateSubroutine(File181, PutRecord) (ByVal(Me, strFile181), ByRef(brrRecord, strRecord181))
;
;===============================================
;
ExternalFunction(File181, Create, typObject) ()
;
;  Create                                        create a class instance
;
  Local(Me, strFile181)

  Me = AllocateMemory(SizeOf(strFile181))
  If IsObject(Me)
    InitializeStructure(Me, strFile181)
    Me\prpVirtualTable   = LabelPtr(File181, VirtualTable)
    Me\priReferenceCount = 1
    Me\proDvsam          = CreateObject(Dvsam)
  EndIf
  ProcedureReturn Me
EndFunction
.
.
.
;
;===============================================
;
;  Virtual Table
;
DataSection
  Label(File181, VirtualTable)
  InterfaceFunction   (File181, Destroy)
  InterfaceFunction   (File181, Clone)
  InterfaceSubroutine (File181, Open)
  InterfaceSubroutine (File181, Close)
.
.
.

And here's what it really means:

Code: Select all

;===============================================
;
;  File181 Class Methods                         Package Menu Items
;
;===============================================
;
;  Properties
;
Structure strFile181
  *prpVirtualTable.I
  priReferenceCount.L
  proDvsam.objDvsam
EndStructure
;
;===============================================
;
;  Declares
;
Declare clsFile181_subGetRecord (*Self.strFile181, *brrRecord.strRecord181)
Declare clsFile181_subPutRecord (*Self.strFile181, *brrRecord.strRecord181)
;
;===============================================
;
Procedure.I clsFile181_funCreate ()
;
;  Create                                        create a class instance
;
  Protected *Self.strFile181

  *Self = AllocateMemory(SizeOf(strFile181))
  If *Self <> 0
    InitializeStructure(*Self, strFile181)
    *Self\prpVirtualTable   = ?clsFile181_lblVirtualTable
    *Self\priReferenceCount = 1
    *Self\proDvsam          = clsDvsam_funCreate()
  EndIf
  ProcedureReturn *Self
EndProcedure
.
.
.
;
;===============================================
;
;  Virtual Table
;
DataSection
  clsFile181_lblVirtualTable:
  Data.I @clsFile181_funDestroy()
  Data.I @clsFile181_funClone()
  Data.I @clsFile181_subOpen()
  Data.I @clsFile181_subClose()
.
.
.

Re: If i had 1000 € to offer for a PB feature...

Posted: Tue Aug 07, 2012 5:56 pm
by Zach
I'm not working on anything spectacular, but I have found EnabledExplicit, as well as the sidebar on the right-hand side of the IDE (Variables, Procedures, Macros, etc) to be very efficient at helping me manage those kinds of issues.

But I also use practical names for my various code objects that are self indicative of what they do and what they are for, so I don't often run into name clash problems..