It is currently Mon Sep 28, 2020 6:47 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: ByteVector - OOP
PostPosted: Mon Nov 04, 2019 12:15 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Jul 07, 2013 11:35 am
Posts: 535
Location: Canada
Hello everyone,

A code that I needed for my 3D game project but that could be useful for something else

Code:
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : ByteVector
; File Name : ByteVector - OOP.pb
; File version: 1.1.0
; Programming : OK
; Programmed by : StarBootics
; Date : 13-04-2019
; Last Update : 04-11-2019
; PureBasic code : V5.71 LTS
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

DeclareModule ByteVector

  Interface ByteVector

    ElementCount.l()
    GetElement.b(Index.l)
    SetElement(Index.l, Element.b)
    PushBack(Element.b)
    PopBack()
    Clear()
    WriteByteVector(FileID.i)
    ReadByteVector(FileID.i)
    Free()

  EndInterface

  Declare.i New(P_ElementCount.l)

EndDeclareModule

Module ByteVector

  Structure Private_Members

    VirtualTable.i
    ElementCount.l
    DataPointer.i
 
  EndStructure
 
  Macro ReachElement(StartPtr, Index)
   
    (StartPtr + (Index) * SizeOf(Byte))
   
  EndMacro
 
  Macro IsBetween(Value, Lower, Upper)
   
    ((Value) >= (Lower) And (Value) <= (Upper))
   
  EndMacro
 
  Procedure.l ElementCount(*This.Private_Members)

    ProcedureReturn *This\ElementCount
  EndProcedure
 
  Procedure.b GetElement(*This.Private_Members, Index.l)
   
    If IsBetween(Index, 0, *This\ElementCount)
      If *This\DataPointer <> #Null
        Output.b = PeekB(ReachElement(*This\DataPointer, Index))
      EndIf
    Else
      DebuggerError("Byte Vector : Index out of bound !")
    EndIf
   
    ProcedureReturn Output
  EndProcedure
 
  Procedure SetElement(*This.Private_Members, Index.l, Element.b)
   
    If IsBetween(Index, 0, *This\ElementCount)
      If *This\DataPointer <> #Null
        PokeB(ReachElement(*This\DataPointer, Index), Element)
      EndIf
    Else
      DebuggerError("Byte Vector : Index out of bound !")
    EndIf
   
  EndProcedure
 
  Procedure PushBack(*This.Private_Members, Element.b)
   
    If *This\DataPointer <> #Null
      OldMemorySize = MemorySize(*This\DataPointer)
    Else
      OldMemorySize = 0
    EndIf
   
    NewMemory = AllocateMemory(OldMemorySize + SizeOf(Byte))
   
    If *This\DataPointer <> #Null
      CopyMemory(*This\DataPointer, NewMemory, MemorySize(*This\DataPointer))
      PokeB(NewMemory + MemorySize(*This\DataPointer), Element)
    Else
      PokeB(NewMemory, Element)
    EndIf
   
    If *This\DataPointer <> #Null
      FreeMemory(*This\DataPointer)
    EndIf
   
    *This\DataPointer = NewMemory
    *This\ElementCount = MemorySize(*This\DataPointer) / SizeOf(Byte) - 1
   
  EndProcedure
 
  Procedure PopBack(*This.Private_Members)
   
    If *This\DataPointer <> #Null
      NewMemorySize = MemorySize(*This\DataPointer) - SizeOf(Byte)
      If NewMemorySize >= SizeOf(Byte)
        NewMemory = AllocateMemory(NewMemorySize)
        CopyMemory(*This\DataPointer, NewMemory, MemorySize(NewMemory))
        FreeMemory(*This\DataPointer)
        *This\DataPointer = NewMemory
        *This\ElementCount = MemorySize(*This\DataPointer) / SizeOf(Byte) - 1
      Else
        FreeMemory(*This\DataPointer)
        *This\DataPointer = #Null
        *This\ElementCount = -1
      EndIf
     
    EndIf
   
  EndProcedure
 
  Procedure Clear(*This.Private_Members)
   
    If *This\DataPointer <> #Null
      FreeMemory(*This\DataPointer)
      *This\DataPointer = #Null
      *This\ElementCount = -1
    EndIf
   
  EndProcedure
 
  Procedure WriteByteVector(*This.Private_Members, FileID.i)
   
    If *This\DataPointer <> #Null
      WriteLong(FileID, MemorySize(*This\DataPointer) / SizeOf(Byte))
      WriteData(FileID, *This\DataPointer, MemorySize(*This\DataPointer))
    Else
      WriteLong(FileID, 0)
    EndIf
   
  EndProcedure
 
  Procedure ReadByteVector(*This.Private_Members, FileID.i)
   
    ElementCount = ReadLong(FileID)
   
    If ElementCount >= 1
     
      If *This\DataPointer <> #Null
        FreeMemory(*This\DataPointer)
      EndIf
     
      *This\DataPointer = AllocateMemory(ElementCount * SizeOf(Byte))
      ReadData(FileID, *This\DataPointer, MemorySize(*This\DataPointer))
      *This\ElementCount = MemorySize(*This\DataPointer) / SizeOf(Byte) - 1
     
    EndIf

  EndProcedure
 
  Procedure Free(*This.Private_Members)
   
    If *This\DataPointer <> #Null
      FreeMemory(*This\DataPointer)
      *This\DataPointer = #Null
    EndIf
   
    ClearStructure(*This, Private_Members)
    FreeStructure(*This)

  EndProcedure

  Procedure.i New(P_ElementCount.l)

    *This.Private_Members = AllocateStructure(Private_Members)
    *This\VirtualTable = ?START_METHODS
       
    If P_ElementCount >= 1
      *This\DataPointer = AllocateMemory(P_ElementCount * SizeOf(Byte))
      *This\ElementCount = MemorySize(*This\DataPointer) / SizeOf(Byte) - 1
    EndIf
   
    ProcedureReturn *This
  EndProcedure

  DataSection
    START_METHODS:
    Data.i @ElementCount()
    Data.i @GetElement()
    Data.i @SetElement()
    Data.i @PushBack()
    Data.i @PopBack()
    Data.i @Clear()
    Data.i @WriteByteVector()
    Data.i @ReadByteVector()
    Data.i @Free()
    END_METHODS:
  EndDataSection

EndModule

CompilerIf #PB_Compiler_IsMainFile
 
  Debug "-------------------------------------------"
  Debug "Let's create a ByteVector of 5 elements"
 
  Vector1.ByteVector::ByteVector = ByteVector::New(5)
 
  For Index = 0 To Vector1\ElementCount()
    Vector1\SetElement(Index, Index*2)
  Next
 
  Debug "-------------------------------------------"
  Debug "Show the elements"
 
  For Index = 0 To Vector1\ElementCount()
    Debug Vector1\GetElement(Index)
  Next
 
  Debug "-------------------------------------------"
  Debug "Save the Vector in a binary file"
 
  If CreateFile(0, "ByteVector.bin")
    Vector1\WriteByteVector(0)
    CloseFile(0)
  EndIf
 
  Debug "-------------------------------------------"
  Debug "Load from a binary file"
 
  If ReadFile(0, "ByteVector.bin")
    Vector2.ByteVector::ByteVector = ByteVector::New(0)
    Vector2\ReadByteVector(0)
    CloseFile(0)
    DeleteFile("ByteVector.bin")
  EndIf
 
  Debug "-------------------------------------------"
  Debug "Show the content from the binary file"
 
  For Index = 0 To Vector2\ElementCount()
    Debug Vector2\GetElement(Index)
  Next
 
  Debug "-------------------------------------------"
  Debug "Let's try the PushBack function"
 
  Vector3.ByteVector::ByteVector = ByteVector::New(0)
 
  Vector3\PushBack(25)
  Vector3\PushBack(35)
  Vector3\PushBack(45)
  Vector3\PushBack(55)
  Vector3\PushBack(65)
 
  Debug "-------------------------------------------"
  Debug "Show the content after 5 PushBacks"
 
  For Index = 0 To Vector3\ElementCount()
    Debug Vector3\GetElement(Index)
  Next
 
  Debug "-------------------------------------------"
  Debug "Show the content after 2 PopBacks"
 
  Vector3\PopBack()
  Vector3\PopBack()
 
  For Index = 0 To Vector3\ElementCount()
    Debug Vector3\GetElement(Index)
  Next
 
  Vector1\Free()
  Vector2\Free()
  Vector3\Free()
 
CompilerEndIf

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<

Best regards
StarBootics

_________________
The Stone Age did not end due to a shortage of stones !


Top
 Profile  
Reply with quote  
 Post subject: Re: ByteVector - OOP
PostPosted: Wed Nov 20, 2019 9:56 pm 
Offline
Addict
Addict
User avatar

Joined: Sat Feb 13, 2010 3:45 pm
Posts: 1132
I'm referring to this posting by you. I think that you have made life difficult by yourself with your code above.

I once tried to get your code to run with lists. This makes the code a lot clearer, shorter and more secure against memory leaks. Only if you really have a lot of vectors (say over 100k) I would organize it with a single global list, because creating a list takes a lot of overhead.

Code:
EnableExplicit

DeclareModule ByteVector

  Interface ByteVector
    Destroy()
    NboElements()
    GetElement(Index)
    SetElement(Element)
    PushBack(Element)
    PopBack()
    Clear()
    WriteByteVector(FileID)
    ReadByteVector(FileID)
  EndInterface

  Declare.i New()

EndDeclareModule

Module ByteVector

  Structure Private_Members
    VirtualTable.i
    List Elements.b()
  EndStructure

  Procedure.i New                      ()
    Protected *This.Private_Members

    *This              = AllocateStructure(Private_Members)
    *This\VirtualTable = ?START_METHODS

    ProcedureReturn *This

  EndProcedure
  Procedure   Destroy                  (*This.Private_Members)

    FreeStructure (*This)

  EndProcedure
  Procedure.i GetNboElements           (*This.Private_Members)

    ProcedureReturn ListSize (*This\Elements())

  EndProcedure
  Procedure.i GetElement               (*This.Private_Members, Index)

    If SelectElement (*This\Elements(), Index-1)
      ProcedureReturn *This\Elements()
    Else
      DebuggerError ("Byte Vector : Index out of bound !")
    EndIf

  EndProcedure
  Procedure   SetElement               (*This.Private_Members, Element)

    LastElement   (*This\Elements())
    AddElement (*This\Elements())
    *This\Elements() = Element

  EndProcedure
  Procedure   PushBack                 (*This.Private_Members, Element)

    LastElement   (*This\Elements())
    AddElement (*This\Elements())
    *This\Elements() = Element

  EndProcedure
  Procedure   PopBack                  (*This.Private_Members)

    LastElement   (*This\Elements())
    DeleteElement (*This\Elements())

  EndProcedure
  Procedure   Clear                    (*This.Private_Members)

    ClearList (*This\Elements())

  EndProcedure
  Procedure   WriteByteVector          (*This.Private_Members, FileID)

    WriteLong(FileID, ListSize (*This\Elements()))
    ForEach *This\Elements()
      WriteByte (FileID, *This\Elements())
    Next

  EndProcedure
  Procedure   ReadByteVector           (*This.Private_Members, FileID)
    Protected nboElements
    Protected i

    nboElements = ReadLong (FileID)
    For i = 1 To nboElements
      AddElement (*This\Elements())
      *This\Elements() = ReadByte (FileID)
    Next

  EndProcedure

  DataSection
    START_METHODS:
    Data.i @Destroy()
    Data.i @GetNboElements()
    Data.i @GetElement()
    Data.i @SetElement()
    Data.i @PushBack()
    Data.i @PopBack()
    Data.i @Clear()
    Data.i @WriteByteVector()
    Data.i @ReadByteVector()
    END_METHODS:
  EndDataSection

EndModule

DisableExplicit


CompilerIf #PB_Compiler_IsMainFile

  Debug "-------------------------------------------"
  Debug "Let's create a ByteVector of 5 elements"
  Vector1.ByteVector::ByteVector = ByteVector::New()
  For Index = 1 To 5
    Vector1\SetElement(Index*2-2)
  Next

  Debug "-------------------------------------------"
  Debug "Show the elements"
  For Index = 1 To Vector1\NboElements()
    Debug Vector1\GetElement(Index)
  Next

  Debug "-------------------------------------------"
  Debug "Save the Vector in a binary file"
  If CreateFile(0, "ByteVector.bin")
    Vector1\WriteByteVector(0)
    CloseFile(0)
  EndIf

  Debug "-------------------------------------------"
  Debug "Load from a binary file"
  If ReadFile(0, "ByteVector.bin")
    Vector2.ByteVector::ByteVector = ByteVector::New()
    Vector2\ReadByteVector(0)
    CloseFile(0)
    DeleteFile("ByteVector.bin")
  EndIf

  Debug "-------------------------------------------"
  Debug "Show the content from the binary file"
  For Index = 1 To Vector2\NboElements()
    Debug Vector2\GetElement(Index)
  Next

  Debug "-------------------------------------------"
  Debug "Let's try the PushBack function"
  Vector3.ByteVector::ByteVector = ByteVector::New()
  Vector3\PushBack(25)
  Vector3\PushBack(35)
  Vector3\PushBack(45)
  Vector3\PushBack(55)
  Vector3\PushBack(65)

  Debug "-------------------------------------------"
  Debug "Show the content after 5 PushBacks"
  For Index = 1 To Vector3\NboElements()
    Debug Vector3\GetElement(Index)
  Next

  Debug "-------------------------------------------"
  Debug "Show the content after 2 PopBacks"
  Vector3\PopBack()
  Vector3\PopBack()

  For Index = 1 To Vector3\NboElements()
    Debug Vector3\GetElement(Index)
  Next

  Vector1\Destroy()
  Vector2\Destroy()
  Vector3\Destroy()

CompilerEndIf

_________________
sorry for my bad english


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 20 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye