Running an agent/edict/rule once when creating a note

Can someone remind me the best approach to setting a Note’s attribute based on some other attribute when first creating a new note?

I’m keeping a meal log in Tinderbox. Each entry contains Meal (Breakfast|Lunch|Dinner), MealType (Fast food|Dine out|Home cooked), and Quality (High|Medium|Low).

I would like the badge to be set based on Quality. Quality is presumably never going to change, so the badge value only needs to be set once.

I assume the is best served by an Edict on the note, but even that feels wasteful if Quality is not expected to change. I’d rather not use a Stamp since the value can easily be derived so a Stamp shouldn’t be necessary.

Am I over thinking this? I’m happy with hearing “Just use an Edict” but thought I’d see if there was a better approach.

I would probably have an agent that looks for notes with the meal log 𝓹𝓻𝓸𝓽𝓸𝓽𝔂𝓹𝓮 and no badge setting. Then the agent sets the badge. At that point, there is nothing for the agent to find until you log the next meal note.

Another trick is to use an on-add action that initially sets the prototype for new notes to a prototype that has a badge-setting rule, and that rule sets the badge then sets the note to a prototype with the same KAs but that does not have a badge-setting rule. So in essence the rule only runs once then disappears from the note after the badge is set.

1 Like

Good tips, thanks. I’ll probably keep it simple and go with your agent-based approach. No sense having an Edict/Rule on every meal note.

I’ll keep my eyes peeled for an “onChange()” event handler of some sort. :slight_smile:

I believe that for cases like this edicts will be less resource intensive than agents. Yes, the edict will fire needlessly once an hour forever, but agents search through every note every few seconds.

I tend to prefer edicts for exactly this type of task, when the edict’s action doesn’t depend on any other note’s state, because unlike agent actions they fire immediately and are (I believe) less resource intensive than agents.

If you’re really bothered by the edicts firing needlessly, you could always add this to the end of the Meal prototype’s $Edict:

if ($Badge & ! $IsPrototype) { $Edict=""; }

Which is why I suggested a self-destructing rule. Runs once, kills itself, and never appears again.

Ah, I have many files in which I want to perform a similar function: set an attribute once, and then leave it alone. This self-erasing rule approach, via the switch in prototypes, is an elegant answer. Will put it to use.

Mark A. discusses a couple of other one-time techniques here. Using a $ShouldRun boolean to bypass the rule. Or flipping on the standard $RuleDisabled attribute once a rule is run.

1 Like

I’m not sure it’s worth worrying too much about unnecessary edicts. Edicts run at startup, before export, and roughly once an hour; that’s not a big computational load.

Still, the techniques described here are great.

1 Like