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)

P.S: This is going to be included in the GitHub repository you can access freely by following the link in my signature.