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

Everything else that doesn't fall into one of the other PB categories.
User avatar
TI-994A
Addict
Addict
Posts: 2698
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

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

Post 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)
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
electrochrisso
Addict
Addict
Posts: 989
Joined: Mon May 14, 2007 2:13 am
Location: Darling River

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

Post 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.
PureBasic! Purely the best 8)
fromVB
User
User
Posts: 82
Joined: Sun Jul 29, 2012 2:27 am

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

Post 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?
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

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

Post 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.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Shield
Addict
Addict
Posts: 1021
Joined: Fri Jan 21, 2011 8:25 am
Location: 'stralia!
Contact:

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

Post by Shield »

Except PB usually doesn't stand a chance in everyday cases against .NET. :wink:
Image
Blog: Why Does It Suck? (http://whydoesitsuck.com/)
"You can disagree with me as much as you want, but during this talk, by definition, anybody who disagrees is stupid and ugly."
- Linus Torvalds
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

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

Post 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. ;)
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

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

Post 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.
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

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

Post 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).
"Have you tried turning it off and on again ?"
A little PureBasic review
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

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

Post 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
;===============================================
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
endo
Enthusiast
Enthusiast
Posts: 141
Joined: Fri Apr 30, 2004 10:44 pm
Location: Turkiye (istanbul)
Contact:

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

Post 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.
-= endo (registered user of purebasic since 98) =-
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

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

Post 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()
.
.
.
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
Zach
Addict
Addict
Posts: 1675
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

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

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