[Utility] DataGrid Container Module

Share your advanced PureBasic knowledge/code with the community.
IndigoFuzz

[Utility] DataGrid Container Module

Post by IndigoFuzz »

Hey all,

I'd like to share a data container module I've written to provide the solution of storing structured data in a resizable 2-dimensional grid (much like multidimensional arrays, but with the ability to resize both dimensions).

There may be one or two teething problems at the moment, but here is the first revision with example included.

Code: Select all

; ====================================================================================================
; Title:        DataGrid Container Module
; Description:  Provides a 2-dimensional container for storing structured data
; Author:       Michael 'Micah' King (micah@indigofuzz.co.uk)
; Revision:     2 (02 FEB 2016)
; License:      Any improvements to be shared with the community.
; Website:      http://www.indigofuzz.co.uk
; ====================================================================================================

;- DataGrid Module Declaration
DeclareModule DataGrid
    
  Declare.i Create(Width, Height, CellSize) ; Create a new DataGrid Instance
  Declare.i CellAt(*Grid, X, Y) ; Retrieve the pointer for a cell for retrieval/manipulation
  Declare.i Width(*Grid) ; Return the width (in cells) of the DataGrid
  Declare.i Height(*Grid) ; Return the height (in cells) of the DataGrid
  Declare Resize(*Grid, Width, Height) ; Resize the DataGrid
  Declare Free(*Grid) ; Release Memory
  
EndDeclareModule

;- DataGrid Module Implementation
Module DataGrid
  
  Structure DATAGRID
    width.i
    height.i
    elementSize.i
    *elements
  EndStructure
  
  Procedure.i coffset(X, Y, Height, Size)
    ProcedureReturn (Y + (X * Height)) * Size
  EndProcedure
  
  Procedure.i Create(Width, Height, CellSize); Allocate a new DataGrid
    If Width > -1 And Height > -1
      Define *instance.DATAGRID = AllocateMemory(SizeOf(DATAGRID))
      InitializeStructure(*instance, DATAGRID)
      *instance\width = Width
      *instance\height = Height
      *instance\elementSize = CellSize
      *instance\elements = AllocateMemory((Width * Height) * CellSize)
      ProcedureReturn *instance
    EndIf
    ProcedureReturn #Null
  EndProcedure
   
  Procedure.i Resize(*Grid, Width, Height)
    Protected *cast.DATAGRID = *Grid
    Protected *temp, x, y
    If *cast And Width > -1 And Height > -1
      If Width <> *cast\width Or Height <> *cast\height
        With *cast
          *temp = AllocateMemory((Width * Height) * \elementSize)
          If *temp
            For x = 0 To \width - 1
              For y = 0 To \height - 1
                If coffset(x, y, Height, \elementSize) < (Width * Height) * \elementSize
                  CopyMemory(\elements + coffset(x, y, \height, \elementSize), *temp + coffset(x, y, Height, \elementSize), \elementSize)
                EndIf
              Next
            Next
            FreeMemory(\elements)
            \width = Width
            \height = Height
            \elements = *temp
            ProcedureReturn #True
          EndIf
          ProcedureReturn #False
        EndWith
      EndIf
    EndIf
  EndProcedure
  
  Procedure.i CellAt(*Grid, X, Y)
    Protected *cast.DATAGRID = *Grid
    If *cast And X > -1 And Y > -1
      If X < *cast\width And Y < *cast\height
        ProcedureReturn *cast\elements + coffset(X, Y, *cast\height, *cast\elementSize)
      EndIf
    EndIf
  EndProcedure
  
  Procedure.i Width(*Grid)
    Protected *cast.DATAGRID = *Grid
    If *cast
      ProcedureReturn *cast\width
    EndIf
  EndProcedure
  
  Procedure.i Height(*Grid)
    Protected *cast.DATAGRID = *Grid
    If *cast
      ProcedureReturn *cast\height
    EndIf
  EndProcedure
  
  Procedure Free(*Grid)
    Protected *cast.DATAGRID = *Grid
    If *cast
      FreeMemory(*cast\elements)
      *cast\elementSize = 0
      *cast\width = 0
      *cast\height = 0
      FreeMemory(*cast)
    EndIf
  EndProcedure
  
EndModule

; == EXAMPLE START ==

EnableExplicit

Structure Element
  message.s
EndStructure

Define *data = DataGrid::Create(2, 2, SizeOf(Element))
Define *cell.Element
Define X, Y

*cell = DataGrid::CellAt(*data, 0, 0) : *cell\message = "Hello"
*cell = DataGrid::CellAt(*data, 0, 1) : *cell\message = "World"
*cell = DataGrid::CellAt(*data, 1, 0) : *cell\message = "This is a"
*cell = DataGrid::CellAt(*data, 1, 1) : *cell\message = "Demonstration"

For X = 1 To DataGrid::Width(*data)
  For Y = 1 To DataGrid::Height(*data)
    *cell.Element = DataGrid::CellAt(*data, X - 1, Y -1)
    Debug "[" + Str(X - 1) + "," +  Str(Y - 1) + "] : " + *cell\message
  Next
Next

Debug "Grid Resized"
DataGrid::Resize(*data, 6, 2)

For X = 1 To DataGrid::Width(*data)
  For Y = 1 To DataGrid::Height(*data)
    *cell.Element = DataGrid::CellAt(*data, X - 1, Y - 1)
    If *cell
      Debug "[" + Str(X - 1) + "," +  Str(Y - 1) + "] : " + *cell\message
    EndIf
  Next
Next

Debug "Grid Resized"
DataGrid::Resize(*data, 1, 5)

For X = 1 To DataGrid::Width(*data)
  For Y = 1 To DataGrid::Height(*data)
    *cell.Element = DataGrid::CellAt(*data, X - 1, Y - 1)
    If *cell
      Debug "[" + Str(X - 1) + "," +  Str(Y - 1) + "] : " + *cell\message
    EndIf
  Next
Next

DataGrid::Free(*data)
Please let me know how you get on :)


P.S: This is going to be included in the GitHub repository you can access freely by following the link in my signature.
Last edited by IndigoFuzz on Wed Feb 03, 2016 4:29 pm, edited 3 times in total.
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2139
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

Re: [Utility] DataGrid Container Module

Post by Andre »

I just did a small test on MacOS 10.6.8 with PB5.42 beta1.

Using this I got an IMA at the Debug command line 142, just after the following debug output:
[0,0] : Hello
[0,1] : World
[1,0] : This is a
[1,1] : Demonstration
Grid Resized
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
IndigoFuzz

Re: [Utility] DataGrid Container Module

Post by IndigoFuzz »

Andre wrote:I just did a small test on MacOS 10.6.8 with PB5.42 beta1.

Using this I got an IMA at the Debug command line 142, just after the following debug output:
[0,0] : Hello
[0,1] : World
[1,0] : This is a
[1,1] : Demonstration
Grid Resized
Hi Andre,

Thanks for the feedback... Hmm, I shall look into why and get that fixed immediately :)
IndigoFuzz

Re: [Utility] DataGrid Container Module

Post by IndigoFuzz »

New revision added which changes the Resizing process. Hopefully this fixes the issue, @Andre :)
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2139
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

Re: [Utility] DataGrid Container Module

Post by Andre »

IndigoFuzz wrote:New revision added which changes the Resizing process. Hopefully this fixes the issue, @Andre :)
I'm on my Win8.1 laptop with PB5.41 LTS this evening.
Here your code seems to run very well, and gives following debug output (MacOS not tested yet):
[0,0] : Hello
[0,1] : World
[1,0] : This is a
[1,1] : Demonstration
Grid Resized
[0,0] : Hello
[0,1] : World
[1,0] : This is a
[1,1] : Demonstration
[2,0] :
[2,1] :
[3,0] :
[3,1] :
[4,0] :
[4,1] :
[5,0] :
[5,1] :
Grid Resized
[0,0] : Hello
[0,1] : World
[0,2] :
[0,3] :
[0,4] :
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
IndigoFuzz

Re: [Utility] DataGrid Container Module

Post by IndigoFuzz »

Andre wrote:
IndigoFuzz wrote:New revision added which changes the Resizing process. Hopefully this fixes the issue, @Andre :)
I'm on my Win8.1 laptop with PB5.41 LTS this evening.
Here your code seems to run very well, and gives following debug output (MacOS not tested yet):
[0,0] : Hello
[0,1] : World
[1,0] : This is a
[1,1] : Demonstration
Grid Resized
[0,0] : Hello
[0,1] : World
[1,0] : This is a
[1,1] : Demonstration
[2,0] :
[2,1] :
[3,0] :
[3,1] :
[4,0] :
[4,1] :
[5,0] :
[5,1] :
Grid Resized
[0,0] : Hello
[0,1] : World
[0,2] :
[0,3] :
[0,4] :
Excellent news :) Thanks for testing (though I am quite apprehensive about MacOS haha)
Post Reply