Page 1 of 1

Udemy formation about OOP with PB

Posted: Sat Apr 06, 2019 8:55 am
by microdevweb
Hey guys,

I created a formation on udemy platform about oop concepts and Pb (sorry but this formation is in french language)

i put some free tickets for you here

https://www.udemy.com/purebasic-program ... de=MCW_POO

For example i teach you how create a database table, this example is using multi heritage class and also abstract methods

Image

needed code for this example without class code (labels are multilingual)

Code: Select all

; **************************************************************************************************
; AUTHEUR : BIELEN PIERRE
; PROJECT : TAB
; MODULE  : TESTE_01.pbi
; **************************************************************************************************
Define flags = #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget
Global.OBJ::DB_TAB myTab
Global.OBJ::DB_TAB_CL_TEXT clName,clSurname
#DB_NAME = "dbTest.db"
Procedure exit()
  End
EndProcedure

Procedure createDbTest()
  If FileSize(#DB_NAME) = -1
    Protected db.OBJ::SQL
    db = SQL::new(#DB_NAME)
    ; création de la table person"
    db\update("CREATE TABLE IF NOT EXISTS 'person' ("+
              "id INTEGER PRIMARY KEY AUTOINCREMENT,"+
              "name TEXT,"+
              "surname TEXT)")
    Protected req.s = "INSERT INTO person (name,surname) VALUES (?,?)"
    Protected i
    For i = 1 To 101
      db\setString(0,"name_"+Str(i))
      db\setString(1,"surname_1"+Str(i))
      db\update(req)
    Next
    db\close()
    
  EndIf
EndProcedure

Procedure resize()
  ResizeGadget(0,0,0,WindowWidth(0),WindowHeight(0))
EndProcedure

createDbTest()

OpenWindow(0,0,0,800,600,"TESTE_01",flags)
ContainerGadget(0,0,0,800,600,#PB_Container_Raised)
BindEvent(#PB_Event_CloseWindow,@exit())
BindEvent(#PB_Event_SizeWindow,@resize())

myTab = DB_TAB::new(#DB_NAME,"person")
myTab\setTitle(LB::new("Person list"+Chr(10)+"Liste des personnes"))
clName = myTab\addColumn(DB_TAB_CL_TEXT::new(LB::new("name"+Chr(10)+"prénom"),"name",0.5))
clSurname = myTab\addColumn(DB_TAB_CL_TEXT::new(LB::new("surname"+Chr(10)+"nom"),"surname",0.5))
clName\setSortEnable(#True)
clSurname\setSortEnable(#True)

myTab\build(0)

Repeat : WaitWindowEvent() : ForEver

Re: Udemy formation about OOP with PB

Posted: Sat Apr 06, 2019 3:44 pm
by SparrowhawkMMU
C'est très généreux, merci :)

Re: Udemy formation about OOP with PB

Posted: Sun Apr 07, 2019 1:51 am
by StarBootics
Hello microdevweb,

I have watch the course you are offering for free and I think you forget something. You are Allocating Structure but you don't freeing it somewhere, and this will probably lead to a memory leak. That being said I like your Character example and now I'm considering to create a program similar to Dev-Module and generate a code similar to this :

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : Module OOP
; File Name : Module OOP.pb
; File version: 1.0.0
; Programming : OK
; Programmed by : StarBootics
; Date : 06-04-2019
; Last Update : 06-04-2019
; PureBasic code : V5.70 LTS
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

DeclareModule Characters
  
  Interface Characters
    GetLife.l()
    GetHealth.l()
    GetName.s()
    SetLife(Life.l)
    SetHealth(Health.l)
    SetName(Name.s)
  EndInterface
  
  Declare.i New(Life.l, Health.l, Name.s)
  Declare Delete(*This)
  
EndDeclareModule

Module Characters
  
  Structure Private_Members
    
    VirtualTable.i
    Life.l
    Health.l
    Name.s
    
  EndStructure
  
  Procedure.l GetLife(*This.Private_Members)
    
    ProcedureReturn *This\Life
  EndProcedure
  
  Procedure.l GetHealth(*This.Private_Members)
    
    ProcedureReturn *This\Health
  EndProcedure
  
  Procedure.s GetName(*This.Private_Members)
    
    ProcedureReturn *This\Name
  EndProcedure
  
  Procedure SetLife(*This.Private_Members, Life.l)
    
    *This\Life = Life

  EndProcedure
  
  Procedure SetHealth(*This.Private_Members, Health.l)
    
    *This\Health = Health
    
  EndProcedure
  
  Procedure SetName(*This.Private_Members, Name.s)
    
    *This\Name = Name
    
  EndProcedure
 
  Procedure New(Life.l, Health.l, Name.s)
    
    *This.Private_Members = AllocateStructure(Private_Members)
    *This\VirtualTable = ?S_METHODS
    SetLife(*This, Life)
    SetHealth(*This, Health)
    SetName(*This, Name)
    
    ProcedureReturn *This
  EndProcedure
  
  Procedure Delete(*This)
    
    If *This <> #Null
      ClearStructure(*This, Private_Members)
      FreeStructure(*This)
    EndIf

  EndProcedure

  DataSection 
    S_METHODS:
    Data.i @GetLife()
    Data.i @GetHealth()
    Data.i @GetName()
    Data.i @SetLife()
    Data.i @SetHealth()
    Data.i @SetName()
    E_METHODS:
  EndDataSection 
  
EndModule

CompilerIf #PB_Compiler_IsMainFile
  
  NewList Characters.Characters::Characters()
  
  AddElement(Characters())
  Characters() = Characters::New(10, 100, "Peter")
  
  Debug "Character Life : " + Str(Characters()\GetLife())
  Debug "Character Health : " + Str(Characters()\GetHealth())
  Debug "Character Name : " + Characters()\GetName()
  
  AddElement(Characters())
  Characters() = Characters::New(11, 95, "Jack")
  
  Debug "-------------------------------------"
  Debug "Character Life : " + Str(Characters()\GetLife())
  Debug "Character Health : " + Str(Characters()\GetHealth())
  Debug "Character Name : " + Characters()\GetName()
  
  Characters()\SetName("StarBootics")
  Characters()\SetLife(12)
  Characters()\SetHealth(100)
  
  Debug "-------------------------------------"
  Debug "Character Life : " + Str(Characters()\GetLife())
  Debug "Character Health : " + Str(Characters()\GetHealth())
  Debug "Character Name : " + Characters()\GetName()
  
  Characters::Delete(Characters())
  DeleteElement(Characters())
  
  Debug "-------------------------------------"
  
  ForEach Characters()
    Debug "Character Life : " + Str(Characters()\GetLife())
    Debug "Character Health : " + Str(Characters()\GetHealth())
    Debug "Character Name : " + Characters()\GetName()
  Next
  
CompilerEndIf

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
Best regards
StarBootics

Re: Udemy formation about OOP with PB

Posted: Sun Apr 07, 2019 7:56 am
by Josh
@StarBootics

You're absolutely right. The destructor is of course one of the central elements of an object. This is one of the main reasons why I use my simple self-knitted OOP system. The destructor of course does some more things, such as:
  • Close opened windows
  • Free allocated memory
  • Close opend files
  • ...
  • Remove itself or
  • Close the app (only main-object)
In my case, I go one step further:
  • The destructor is a method of the object
  • When creating an object, a parent object is specified in the procedure parameters.
    Only the main object 'App' has no parent object.
  • When the object is created, it enters itself in a list with a reference to the parent object.
  • When I call the destructor of any object, the following happens:
    • The first thing the destructor does is search the list for child objects.
    • If there are child objects, the destructor of the child object is called.
    • The destructor of the child object of course does the same and searches
      first whether it has child objects itself.
So recursively all objects are released and there is no danger to forget anything.

Re: Udemy formation about OOP with PB

Posted: Sun Apr 07, 2019 8:18 am
by microdevweb
@StarBootics,

don't worry i explain section 26 how destruct the instance of objet. For dot it i don't use directly FreeStructure but i call a method for destruct all linked objects.

example with the class form

Code: Select all

Procedure free(*this._struct)
    With *this
      ForEach \myContent()
        \myContent()\free()
        \title\free()
      Next
      ForEach \myCallBack()
        \myCallBack()\free()
      Next
      FreeStructure(*this)
    EndWith
  EndProcedure
other example my class sql when we close database we free also this object instance

Re: Udemy formation about OOP with PB

Posted: Sun Apr 07, 2019 1:58 pm
by mk-soft
Each class should include the method Release and perhaps AddRef to protect the object when used multiple times.
So, like the interface "IUnknown"

My internal functions Initialize and Dispose are also called in the correct order when inherited.
In these functions the necessary functions are called to create or release additional memory.

Re: Udemy formation about OOP with PB

Posted: Mon Sep 16, 2019 1:55 am
by Mistrel
As useful as OOP in PureBasic may at first appear, it is a complete dead-end. One very glaring point is that the language doesn't support even basic call chains for methods.

For example:

Code: Select all

Interface BoxObject
EndInterface

Structure SomeObject
  getBox.BoxObject
EndStructure

*obj.SomeObject=0

; [Error] Garbage at the end of the line.
Debug *obj\getBox() ; <- Can't do it
For a much more lengthy explanation:

viewtopic.php?f=13&t=71028

Even as an introduction to OOP, PureBasic very quickly runs into major problems with traditional paradigms necessary for encapsulation as basic as scope. I've submitted a number of feature requests on how these issues can be addressed but I don't know if they will ever make it into the language.

I would recommend taking a look at Lua as a platform for teaching OOP in education. As unlikely as it may seem, this shockingly spartan language can scale from the embarrassingly procedural all the way to fully-featured OOP with classes and inheritance.