It is currently April 26th, 2024, 9:06 pm

Best Practices: Plugin returning lists

Share and get help with Plugins and Addons
derari
Posts: 17
Joined: February 24th, 2011, 5:39 pm

Best Practices: Plugin returning lists

Post by derari »

Hello,

I am writing a plugin that fetches a list (of variable length) of tuples (each tuple is a (string; integer))

I just want to show the values in some kind of tables. What is the best way to access this data from a skin?

I probably have to create multiple measures and meters, as rainmeter does not support complex values(?), but I can't figure out the best way to do it (I dont need ini-code, just give a basic idea).

Thanks,
derari
User avatar
jsmorley
Developer
Posts: 22631
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Best Practices: Plugin returning lists

Post by jsmorley »

I think the way WebParser works might be illustrative.

You have a main plugin measure that goes out and does whatever it is you are doing to create the data elements. That stores them in some kind of array / structure in memory.

Then you have secondary measures, that also call the same plugin, but have a setting of IndexMeasure= or something. (on the main one, you would leave this setting off in the skin) This setting would contain the name of the main measure above. On those "child" measures, you have a setting like IndexNumber= or something, that would "pick off" the requested data element from the array and return it.

You are right that you can only return only one thing at a time in a measure. It can be either a string or a number.
derari
Posts: 17
Joined: February 24th, 2011, 5:39 pm

Re: Best Practices: Plugin returning lists

Post by derari »

Thank you for your help.

Just to make sure I understand, this will call the plugin for each index, executing the measurement every time?
User avatar
jsmorley
Developer
Posts: 22631
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Best Practices: Plugin returning lists

Post by jsmorley »

derari wrote:Thank you for your help.

Just to make sure I understand, this will call the plugin for each index, executing the measurement every time?
That would not be my understanding of it. What I envision is that you have a plugin. It goes out and does "something", which returns a bunch of data as elements in some kind of array / vector / linked list, whatever is appropriate. When the same plugin is used with keys of "IndexMeasure=" and "IndexNumber=" on another plugin measure later, instead of doing "something" again, it knows that this is now requesting that the data element "IndexNumber" from the previous execution be returned. You control having multiple executions of the plugin as a "parent" measure by identifying the results with a name associated with the [MeasureName] that called it.

[Measure1]
Measure=Plugin
Plugin=MyPlugin.dll

[Measure2]
Measure=Plugin
Plugin=MyPlugin.dll
IndexMeasure=Measure1
IndexNumber=1

[Measure3]
Measure=Plugin
Plugin=MyPlugin.dll
IndexMeasure=Measure1
IndexNumber=2

[Meter1]
Meter=String
MeasureName=Measure2
X=0
Y=0

[Meter2]
Meter=String
MeasureName=Measure3
X=0
Y=R

I don't know how the fact that you are measuring / collecting "pairs" of related data elements, with the implication that one part is a string and one part a number factors into this.

I will say though that the underlying, unmovable, "built into the DNA" way that Rainmeter works is that from the standpoint of a skin, a measure returns ONE thing per "update".

Then other measures or meters can use that ONE thing in some fashion. It might be to do some calculation, to drive a string meter, bar meter, image meter, whatever.

So you can never have a measure that returns a string and a number at the same time. It also can't return two strings, unless you want to return them as ONE, using a delimter of some kind like " | " or something. However, there is no way inside of Rainmeter to split that string into two for use in two measures or meters.

So I am not suggesting that my method breaks these rules. What it does do, is allow you to have a plugin that does the "hard work" of going out and doing "something" only once, return as much information as you like, and then use subsequent measures that don't have to do the entire "something" again, but just leverage the work the original measure did.
derari
Posts: 17
Joined: February 24th, 2011, 5:39 pm

Re: Best Practices: Plugin returning lists

Post by derari »

So what happens in your example is that the plugin is called for Measure1 and caches the result and then uses the cached result when indexMeasure=Measure1 is set.
User avatar
jsmorley
Developer
Posts: 22631
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Best Practices: Plugin returning lists

Post by jsmorley »

derari wrote:So what happens in your example is that the plugin is called for Measure1 and caches the result and then uses the cached result when indexMeasure=Measure1 is set.
That is my thinking.
derari
Posts: 17
Joined: February 24th, 2011, 5:39 pm

Re: Best Practices: Plugin returning lists

Post by derari »

Will Measure1 be executed automatically in this scenario, or do I have to trigger it manually from the plugin (when evaluating Measure2)?
User avatar
jsmorley
Developer
Posts: 22631
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Best Practices: Plugin returning lists

Post by jsmorley »

We are getting out of my comfort zone as far as my C++ coding skills really, and I prefer to be accurate when getting down in the weeds. I think it would be best if you took a look at the WebParser plugin in our code repository: http://code.google.com/p/rainmeter/source/browse/trunk#trunk%2FPlugins%2FPluginWebParser to see how it does it. My suggested approach is based on my understanding of how this plugin works, and might or might not be the right way to go based on what your plugin is doing.
derari
Posts: 17
Joined: February 24th, 2011, 5:39 pm

Re: Best Practices: Plugin returning lists

Post by derari »

jsmorley wrote: I think it would be best if you took a look at the WebParser plugin
I did that, but it was to much. Maybe I try it again tomorrow.

I was additionally confused by this site: http://rainmeter.net/cms/Tips-MeasureAsVariable. It creates the impression that combining measures is a natural feature of rainmeter. If it is, I could not reproduce it.

So what I did is (I am programming in C#): I added this code to Rainmeter.Settings.InstanceSettings

Code: Select all

                public InstanceSettings GetSection(string section)
                {
                    foreach (InstanceSettings i in PluginSettings.Instances.Values)
                    {
                        if (i.INI_File == INI_File && i.Section == section)
                        {
                            return i;
                        }
                    }
                    return null;
                }
and then evaluated the referenced ini-section myself (and cached the result):

Code: Select all

MyComplexData data;
string sourceRef = Instance.INI_value("IndexMeasure");
if (sourceRef.Length > 0)
{
    Rainmeter.Settings.InstanceSettings source = Instance.GetSection(sourceRef);
    data = Eval(source); // with caching, using timestamps
}
else
{
    data = Eval(Instance);
}
return data[Instance.INI_value("Index")];
User avatar
TD22057
Posts: 30
Joined: February 2nd, 2011, 2:19 am

Re: Best Practices: Plugin returning lists

Post by TD22057 »

My Open Hardware Monitor plugin and the AdvancedCPU plugin (from the Rainmeter source) both do what you're describing (I think). They read a lot of values from some data source and then individual measures request them by name or index. The plugin updates the value list separately from the calls to each measure. You can also check this thread:

http://rainmeter.net/forum/viewtopic.php?f=18&t=6809

where I asked/discussed a few of the different ways to have a background update going on that is then referenced by multiple measures.