iām just having a think about the method iāve used for handling data in my program and think that itās a bit sloppy, and would just like to check for opinions.
my main component (sitting in a dialog window) holds an array of objects. this array is stored there as it is used thruout the program, but there are two āpageā components which operate on the data in different ways.
at the moment, each of these subcomponents are created with a pointer to the array, which they use to access the data. however, iām sure that this is a stupid and naive way of doing things and iād like to get into the habit of doing things sensibly.
what is recommended? do i put all the code that manipulates the data within the main component, and have some kind of callback system? iām not entirely sure how iād implement that kind of thing.
if, for example, a page component wishes to set a value of an object in the array, what would be the best way? at the moment, it simply calls a class member function to perform some operation on the array from the pointer. this just feels like bad practise. should the function that manipulates the data exist within the main component?
actually, obviously itās best that the data live in its own class to handle all manipulation. (thatās very stupid of me to not do that here)ā¦ but how does the page component best tell the data to operate?
iād greatly appreciate any help on this topic. cheers
do i inherit ActionBroadcaster in my page component, and have it send an action message with some defined name; then the main component would have an action for this message which would tell the data to operate?
In oo parlance, each āpageā āis aā thing, but has slightly different ābehaviorsā. This implies inheritance. You can make āpageā a base class, but declare the ādata operationā function virtual, then derive two classes from āpageā, and implement the ādata operationā differently in each. This assumes of course that the interface (calling convention) for the different data operations is the same.
[edit]
Thought Iād also mention that calling functions with parameters is hundreds of times faster than passing messages between JUCE components.
if these page type classes were similarly derived then, how would they actually access the data which is stored in the parent class?
forgetting details, if the main structure looked like this:
class Component maincomponent
{
DataStore data
PageType page1
PageType page2
};
how would page1 and page2 actually access the data? at the moment they recieve a pointer to the DataStore which they use to operate, but something tells me that thatās sloppy, and there should be a more āsolidā method of them accessing the data, perhaps getting the parent to ādoā stuff with it.
for example, if there was a āincrementAllDataValues()ā function they could call - who would actually ādoā that? would they indicate to the maincomponent that they want to do it, and let the parent handle whether or not it should call the function? or should they just do what they do now and call it themselves?
and if they want to retrieve a data value? something tells me that itās better to have a temporary storage in the page; it notifies the maincomponent that it needs a value, the value is retrieved by the maincomponent and stored in the pageās ācurrentValueā space, and then the page is updated? or is it an acceptable method to simply use a pointer within the page to just get it itself?
i feel that it may be ābetterā to keep each class contained, so that the actual ādataStoreā can be independant. does that make sense? or am i needlessly complicating things? iām just wary of developing bad practises when there may be a really tight acceptable way of doing such things.
yes, having a class which contains the data and operations is what i have done (not sure why i didnāt do that in the first place) but actually getting the other components to be able to REFER to an instance of that class stored in a parent component is what i was troubling myself with.
i.e. the āpagesā are stored in the same component as the data; should the pages have direct access to the classes stored in their parent? or just tell the parent that they want to do something with it and the parent tells the data to do it?
iāll look at this singleton thing tho - iāve no idea what that is! :o
possibly. Iām no expert but I see nothing wrong with objects having member variable pointers to objects in the parent.
calling the parent to do something with the data would mean passing a āthisā pointer to the child object. So thats passing a pointer anyway.
or
using juce getParentComponent() which is essentially the same thing but youād have to somehow cast the result to get at any specialised methods ( extensions to base Component ) (which caused me all sorts of circular header file nightmares - I gave up on that and went with resending mouseevents to the parent instead)
so yeah. just give em a pointer unless you like the singleton thang.
i was hoping to see at least one person say something about actionlisteners!
so i inherit an actionbroadcaster, and then send a string message to the parent to instruct it to ādoā something with the data class?
when it comes to actually getting info from the data class tho, what would the approach be?
lets say i want to retrieve a colour from the datastore. is the following approach a sensible one?
(from within page1)
page1::initiateColourRetrieval()
{
sendActionMessage(T("getcolour"));
}
mainParent::actionListenerCallback(const String msg)
{
if (msg == T("getcolour"))
col = dataStore->getColour();
myPage1->giveColour(col);
}
crumbs it all looks rather convoluted...
i imagine if i just wanted to take a number from the store to do a calculation with then this kind of approach is stupid...
am i missing something here? have i just demonstrated a complete misunderstanding of callback technique?
i was hoping to see at least one person say something about actionlisteners!
so i inherit an actionbroadcaster, and then send a string message to the parent to instruct it to ādoā something with the data class?
when it comes to actually getting info from the data class tho, what would the approach be?
lets say i want to retrieve a colour from the datastore. is the following approach a sensible one?
(from within page1)
page1::initiateColourRetrieval()
{
sendActionMessage(T("getcolour"));
}
mainParent::actionListenerCallback(const String msg)
{
if (msg == T("getcolour"))
col = dataStore->getColour();
myPage1->giveColour(col);
}
crumbs it all looks rather convoluted...
i imagine if i just wanted to take a number from the store to do a calculation with then this kind of approach is stupid...
am i missing something here? have i just demonstrated a complete misunderstanding of callback technique?[/quote]
hmmm. don't like that much meself. seems like far too much going on for a simple data retrieval. if mainParent, page1 and page2 all need to speak to the dataStore then just give the fuckers all a pointer keeping mainParent as in charge of creation/deletion.
or if you can see your dataStore as a sort of "global registry" then I fancy the singleton as you can "summon" the bastard from anywhere. I like that way but it has to fit with your design. (you wouldn't want ALL your objects as singletons ALL summonable from ANYWHERE! LOL!)
[code]
page1::initiateColourRetrieval()
{
_colour = DataStore::getInstance()->getColour();
}
[/code]
yes, indeed having callbacks and whatnot for data retrieval does create a lot of red-tape. i can imagine there being times when itās useful, but thereās no point in keeping the main object in charge of everything - after all the page object should dictate its own instructions over the data.
thanks a lot for discussing this guys. itās much easier to see the best options when people help shine their opinions on things.