Layer metadata for scripting

Moho allows users to write new tools and plugins. Discuss scripting ideas and problems here.

Moderators: Víctor Paredes, Belgarath, slowtiger

Post Reply
User avatar
Lost Marble
Site Admin
Posts: 2347
Joined: Tue Aug 03, 2004 6:02 pm
Location: Scotts Valley, California, USA
Contact:

Layer metadata for scripting

Post by Lost Marble »

Something that the advanced scripters among you have been asking for for a while is a way to save data related to a script the Anime document. This is now possible in version 8.2.

It's a feature I've called layer metadata. For every layer in an Anime document there is an LM_Message object that can be retrieved using the Metadata() function. An LM_Message object stores key/value pairs, and you can see it's interface in the pkg_lm_gui.lua_pkg file.

Any values you set in this LM_Message object will get saved with the Anime file, and will be restored when you reopen the document. The Anime application itself will completely ignore this metadata, but your scripts can query this data any time they choose.

Those of you who have asked for this feature probably already know what you want to use it for, but here are some possible examples:

* A script that generates a procedural shape (say a star). Normally, the script would run once and be done. With metadata, you could store the number of points in the star, and if you re-run the script it could modify the existing star instead of creating a new one.

* For embedded scripts, metadata could be used to store and recall complex relationships between bones for intricate 3D movements.

Here's a snipped showing some usage. Note that the first time this script runs, meta:CountKeys() will return 0, so nothing will be printed out. The second time it runs, the data that was saved into the layer's metadata will be printed to the console.

Code: Select all

local meta = moho.layer:Metadata()

if (meta:HasKey("Saved Vector 3")) then
	local v = meta:GetVector3("Saved Vector 3")
	print(v.x, v.y, v.z)
end

print("Layer metadata:")
for i = 0, meta:CountKeys() - 1 do
	local keyName = meta:GetKeyName(i)
	print(keyName, meta:GetString(keyName))
end
meta:Set("Int Value", 42)

meta:Set("Bool Value", true)
meta:Set("StringName", "This is a saved metadata string.")
local v = LM.Vector2:new_local()
v:Set(5.6, 7.8)
meta:Set("Saved Vector 2", v)
local v = LM.Vector3:new_local()
v:Set(3.4, 5.6, 7.8)
meta:Set("Saved Vector 3", v)
One last tip: If the key/value model doesn't quite work for the data you're working with you could always serialize your data as one big string and save that string as one entry.

OK, one more last tip: There's nothing preventing multiple scripts from accessing the same data. This could be a good thing or a bad thing. Good if two scripts are meant to work together, bad if they unexpectedly start changing the values stored by the other script. It might be a good convention to add a prefix to the keys that you use to store values. With that in mind, please avoid using the LM_ prefix. If I start using metadata for something included with the application, I'll use keys like "LM_radius".

-Mike
User avatar
hayasidist
Posts: 3525
Joined: Wed Feb 16, 2011 8:12 pm
Location: Kent, England

Post by hayasidist »

Great feature! - "Prefs" on a layer-by-layer basis! :D

Now that the scripting interface is getting more features, it would be *really* helpful if there was a query function that returned the version of the product (unless there alreday is but I haven't found it yet!). I've been fudging it by (e.g.) testing if MOHO.MohoGlobals is defined ...
Rudiger
Posts: 786
Joined: Sun Dec 18, 2005 2:25 am

Post by Rudiger »

Oh wow. The possibilities are endless! Thanks so much for adding this awesome feature!
Breinmeester
Posts: 303
Joined: Thu May 13, 2010 2:01 pm

Post by Breinmeester »

This is really cool! Thanks, Mike!
Moho keeps getting better... 8)
Post Reply