Page 1 of 1
A design question re: Objects
Posted: Tue Apr 21, 2015 5:22 pm
by gddeluca
OK, I'm porting a tabbed editor from PowerBasic to PureBasic. In PowerBasic, the data related to a single tab instance was defined and manipulated in an Object associated with the tab. This provided great data isolation between tabs and simplified coding greatly.
But I see no Objects in PureBasic, so what would be a recommended way to structure the data in PureBasic? There's probably several hundred variables, some of which are complex structures of their own.
I'd rather start off on the right path, than poke away and then discover, after I'm more familiar with PureBasic and it's capabilities, that there was a much better way.
George
Re: A design question re: Objects
Posted: Tue Apr 21, 2015 6:20 pm
by infratec
Hi,
I'm not sure what you exactly want, but maybe it is this:
You can assign an integer to each gadget with SetGadget(Item)Data().
If you define a structure you can assign the address of this structure to the gadget.
Code: Select all
Structure TestStructure
Integer.i
Text$
EndStructure
Define Test.TestStructure
Define *Test.TestStructure
OpenWindow(0, 0, 0, 190, 100, "SetGadgetData", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0, 10, 10, 80, 20, "Button")
SetGadgetData(0, @Test)
Test\Text$ = "Hello"
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case 0
*Test = GetGadgetData(0)
Debug *Test\Text$
EndSelect
Case #PB_Event_CloseWindow
Exit = #True
EndSelect
Until Exit
This example makes no sense, but it demonstrate what I mean.
Bernd
Re: A design question re: Objects
Posted: Tue Apr 21, 2015 6:26 pm
by spikey
Definitely structures. Just about everything I do ends up in a structure sooner or later, usually sooner.
Arrays, lists, maps can all have a structure. Structures can contain other structures and also can contain arrays, lists and maps, which can all have their own structures, arrays, lists or maps... And as Bernd has already shown these can be attached directly to interface objects using a pointer...
Re: A design question re: Objects
Posted: Tue Apr 21, 2015 7:30 pm
by Danilo
An Object/Class is a data structure combined with procedures/functions/methods that work on that data structure.
Small example using Object 'Document' with PanelGadget (enable Debugger):
Code: Select all
;
;-[ Object 'Document' ]---------------------------------------
;
Structure Document
gadget.i
item.i
tabName.s
fileName.s
EndStructure
Procedure Document_New(name.s, fileName.s="") ; Create new Document
*doc.Document = AllocateMemory( SizeOf(Document) ) ; alloc new Document in memory
If *doc ;
InitializeStructure( *doc, Document ) ; initialize Document structure
*doc\tabName = name ; set Document tabName
*doc\fileName = fileName ; set Document fileName
EndIf
ProcedureReturn *doc
EndProcedure
Procedure Document_AddToPanel(*doc.Document, gadget) ; Add Document to Panel gadget
If *doc
*doc\gadget = gadget
AddGadgetItem(gadget, -1, *doc\tabName)
*doc\item = CountGadgetItems(gadget)-1
SetGadgetItemData(gadget, *doc\item, *doc)
EndIf
ProcedureReturn *doc
EndProcedure
Procedure.i Document_GetGadget(*doc.Document)
If *doc
ProcedureReturn *doc\gadget
EndIf
EndProcedure
Procedure.i Document_GetItem(*doc.Document)
If *doc
ProcedureReturn *doc\item
EndIf
EndProcedure
Procedure.s Document_GetTabName(*doc.Document)
If *doc
ProcedureReturn *doc\tabName
EndIf
EndProcedure
Procedure Document_SetTabName(*doc.Document, name.s)
If *doc
*doc\tabName = name
SetGadgetItemText(*doc\gadget, *doc\item, name)
EndIf
ProcedureReturn *doc
EndProcedure
Procedure.s Document_GetFileName(*doc.Document)
If *doc
ProcedureReturn *doc\fileName
EndIf
EndProcedure
Procedure Document_SetFileName(*doc.Document, fileName.s)
If *doc
*doc\fileName = fileName
EndIf
ProcedureReturn *doc
EndProcedure
;
;-[ End of Object 'Document' ]--------------------------------
;
;-------------------------------------------------------------
;
; Event procedures
;
Procedure TabChanged()
gadget = EventGadget()
currentTab = GetGadgetState( gadget )
*doc.Document = GetGadgetItemData(gadget, currentTab)
If *doc
Debug Document_GetTabName(*doc) +
" on gadget " +
Str( Document_GetGadget(*doc) ) +
", Item: " +
Str( Document_GetItem(*doc) )
Debug " - filename: " + Document_GetFileName(*doc)
EndIf
EndProcedure
;
; Main
;
If OpenWindow(0, 0, 0, 300, 220, "PanelGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
PanelGadget (1, 5, 5, 290, 60)
doc1 = Document_AddToPanel( Document_New("Tab 1"), 1 )
doc2 = Document_AddToPanel( Document_New("Tab 2"), 1 )
doc3 = Document_AddToPanel( Document_New("Tab 3", "c:\myfile.txt"), 1 )
Document_SetFileName(doc1,"abc.txt")
Document_SetTabName( doc1,"abc.txt")
BindGadgetEvent(1,@TabChanged(),#PB_EventType_Change)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Re: A design question re: Objects
Posted: Tue Apr 21, 2015 8:25 pm
by gddeluca
spikey: infratec: OK, thanks. Pretty much as I was thinking. Where PureBasic beats out PowerBasic by a mile is that structures can have basically any data type, including variable length stuff like dynamic strings. In PowerBasic, you have to put dynamic stuff like that into an Object.
What I'd like to do to make porting easier is to keep things as much as possible like the current source structure. So using pointers like infratec suggested would seem to solve things; I just convert my Object full of INSTANCE data into a matching Structure. In the old code I have a pointer to an assigned Object, it would now become a pointer to the equivalent Structure.
I'd really only swap the pointer when the tab is switched, that way I wouldn't have to do it in every gadget event handler. Just have to figure out what event tells me of a tab switch.
Thanks a lot for your advice.
George
P.S. Just about to Submit this and the reply from Danilo came through. Wow! a very good sample of what my first conversion wants to do. Many, many thanks, it's invaluable.
George