Jump to content

Getting "preferences dialog" data or the like, throughout OOP code


Recommended Posts

I still find myself getting stuck in the "old" ways of coding and somewhat have trouble breaking out of them :angry: . I have a question regarding getting something like user preferences throughout code. The way I have done it for years is I have some preferences dialog and a functional global that manages the preferences xml or ini file. When the program starts, the FG loads the file, then if the user updates the preferences from the dialog and saves, the new data is set in the FG and written back to the file. Now, anywhere I need to access the preferences throughout my code I can just use a "get" case on my functional global to get these user preferences. I know I am only writing to the FG from one place (the actual dialog when the user modifies it), so I don't need to worry about race conditions and such.

Now, with OOP, I would load all this data into a class. But, my question is, what is the best way to get that class everywhere I need it? I am guessing the general response will be, "it depends!". Is the best option to have the classes that need the preferences data have a preferences data member, and then send a "preferences updated" message to all processes that need it? What if I'm launching a new window that needs it; should it be set in the initialization of the class associated with that Window?

Just curious what methods others have used. Thanks.

  • Like 1
Link to comment

You can still use a Get method. Just you have to make it a singleton (which is the default for a VI, but you have to program it for classes-e.g use a DVR).

After I posted, this route crossed my mind, just wasn't sure if there was a better way. Do you use this often for ini files and such?

Link to comment

The following is our approach, with which we are quite happy:

We define configuration elements (usually in a cluster). Each configuration element addresses one setting or group of settings, appears on one page of the properties/configuration dialog, and stores in one XML file.

We add configuration elements as attributes (class private data) where needed. (Note that a class may contain multiple configurable elements, and a particular configurable element may appear in multiple classes.)

We have a common configuration editor code and initialization (init) code (to read the files). Our applications allow editing of the configuration only when a component is in a Standby or Off State. Each component has an init method (based on common code) that reads and applies the configuration when we transition from Standby to Disabled State. (The init method for the larger model consists of the set of init methods for the individual classes.) Hence each object has its own configuration.

Link to comment

The following is our approach, with which we are quite happy:

We define configuration elements (usually in a cluster).

Why not have your configuration elements as classes themselves?

Edit: I may have answered my own question (in question format because I'm not 100% sure), but is it because you need them to appear in the config dialog? The cluster allows you to populate something meaningful to the user on the FP?

Edited by for(imstuck)
Link to comment

Why not have your configuration elements as classes themselves?

Edit: I may have answered my own question (in question format because I'm not 100% sure), but is it because you need them to appear in the config dialog? The cluster allows you to populate something meaningful to the user on the FP?

Yes, you answered your question correctly!

In fact, we originally tried to create configuration objects, but

1) Objects don't have front panel representations. (OK, it is possible to make friend XControls for this purpose, but we did not want to go there.)

2) We could still put the clusters inside objects (and in a few legacy cases we still do that) but we found it didn't buy us anything--it just added complexity.

So we just stick with clusters.*

*For completeness: Note that clusters don't have the same version handling mechanism classes do. In practice, that has not been a concern for us in any way. We only deploy our applications at one site, though. If we had many versions in many places I could envision that we might need some way to convert configurations between versions, although even then I expect that wouldn't be much of a problem, provided the released versions were reasonably stable in the first place.)

Link to comment

Yes, you answered your question correctly!

In fact, we originally tried to create configuration objects, but

1) Objects don't have front panel representations. (OK, it is possible to make friend XControls for this purpose, but we did not want to go there.)

2) We could still put the clusters inside objects (and in a few legacy cases we still do that) but we found it didn't buy us anything--it just added complexity.

So we just stick with clusters.*

*For completeness: Note that clusters don't have the same version handling mechanism classes do. In practice, that has not been a concern for us in any way. We only deploy our applications at one site, though. If we had many versions in many places I could envision that we might need some way to convert configurations between versions, although even then I expect that wouldn't be much of a problem, provided the released versions were reasonably stable in the first place.)

With regards to number 1, yes, that would get old quickly, creating X Controls every time you made a new class. I support your decision haha. And with regards to the "for completeness" part, the versioning built into the classes was the main reason I wanted some clarification on why objects were not used.

Link to comment

Nope. Why do you need a cache for prefs? (let the OS do that) Kind of defeats the object.

Because an in-memory lookup is faster than a query + potential hit to disk? Obviously, it works just fine for you, but it just seems wrong to be querying a DB to retrieve a setting - there is actual CPU legwork to be done via the DB route whereas with a FG/whatever, it's just memory retrieval (which, yes, I'll admit could potentially be paged to disk as well).

I'm absolutely not saying you're wrong, but it is a weird paradigm to me.

Link to comment

I am really interested in this topic too and there are a few good threads floating around on LAVA worth searching for

I want each Object to handle this function for themselves for reuse purposes

I like to do it in most cases as per this example here

Link to comment

Why not use some self-displaying objects? Simply incorporate a dialog display routine into your class definition and you have XControl light which allows your objects to display themselves in a subpanel for editing (perfect for Preferences dialogs).

The host program simply juggles Configuration objects and needs to know nothing of the actual configuration settings.

Shane.

Link to comment

This thread seems to have diverged into a few distinct topics:

Original thread topic: How to distribute updated "preferences" data to multiple processes.

Ancillary topic 1: Using classes to define configurable data items.

Ancillary topic 2: Using configurable objects within a "configuration editor" (or "preference dialog").

On the original thread topic:

If multiple processes require configuration and these processes operate as some sort of state machine: there is probably a valid state in which editing configuration should be allowed (and disallowed in other states), and there is probably a transition during which configuration should be loaded and cached within that process.

If other processes requiring the configuration are state-less (except maybe init & run), then they probably need to be signaled to re-init (i.e. reload the configuration from disk, DB, or FGV) after it has been edited.

On topic 1:

There's a tradeoff between the beauty of mutable version handling when loading classes serialized to disk and the convenience of human readable/editable files. If you're attempting to maintain multiple deployments & versions, or if requirements are frequently evolving, then it's probably best to just flatten objects to disk. I find it hard to come up with a compelling case otherwise.

On topic 2:

Shane's suggestion is good, "self-displaying objects", but it's easier said than done. How would you handle a configurable object hierarchy, where each child class contributes its own configurable attributes. After the self-display method is running in a subpanel how do you pass in the current configuration to display, how do you signal it to stop then pass out or retrieve the updated configuration? Is each object in charge of it's own disk read/writes or does the top-level config editor handle it all generically?

There are many right answers here of course, it's not "one-size-fits-all". I find that most solutions are either highly extensible but relatively complex to use and non-trivial to implement, or they are simple but rigid and limiting.

For those of you who have a good solution or idea, please describe context in which it is applicable. I know that Paul's solution described above used on the Discovery Channel Telescope works well for state-based systems that are deployed to one location, undergo little to no change to configuration datatypes, and require separate applications to edit and load configurable items.

  • Like 1
Link to comment

Shane's suggestion is good, "self-displaying objects", but it's easier said than done. How would you handle a configurable object hierarchy, where each child class contributes its own configurable attributes.

I don't have a good answer, but my previous post does link to a couple of examples which demonstrate how this can be handled in two completely separate ways. Not having used either in an actual app, I can't add more than that.

Link to comment

I don't have a good answer, but my previous post does link to a couple of examples which demonstrate how this can be handled in two completely separate ways. Not having used either in an actual app, I can't add more than that.

Well it depends on the usage intended but although it's no neccessarily trivial in itself, it solves a LOT of other encapsulation problems you might otherwise have. You can create new classes after compilation and have the neccessary UI already included since it's a private class method.

Shane.

Link to comment

I've posted a simply example of self-displaying objects on the Dark side. I was actually trying something with DVRs but it shows the principle of self-displaying obejcts also.

Link: http://forums.ni.com...ls/td-p/2126824

Shane.

I was just reading this thread today. Now I have to go actually look at the source code to digest it all.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.