Copy link to clipboard
Copied
Hi gang (Shachar) 😉
Over the last while I have (somewhat) blindly stumbled my way across making my own custom parameter using the Arbitrary parameter, with some additional help.
Now that I've got it working, I wanted to duplicate it to be reused by other custom parameters. However, none of the UI SDK samples show how to use more than one and, since I don't fully understand the system yet, I am stuck. I checked the forum for similar posts and couldn't really find much help either. So I'll ask my questions and hopefully someone can help.
When one creates a custom parameter like below, what else needs to be unique for each custom parameter? Obviously the ID which in this case is CUSTOMUI_DISK_ID. But what about ARB_REFCON? I'm not sure what that is used for - does it also need to be unique for each custom parameter? Finally, what about &def.u.arb_d.dephault? Does that also have to be unique for every arbitrary parameter?
AEFX_CLR_STRUCT(def);
def.flags = PF_ParamFlag_SUPERVISE;
def.ui_flags = PF_PUI_CONTROL;
def.ui_width = UI_BOX_WIDTH;
def.ui_height = UI_BOX_HEIGHT;
ERR(CreateDefaultArb(in_data,
out_data,
&def.u.arb_d.dephault));
PF_ADD_ARBITRARY2("Custom UI",
UI_BOX_WIDTH,
UI_BOX_HEIGHT,
0,
PF_PUI_CONTROL | PF_PUI_DONT_ERASE_CONTROL,
def.u.arb_d.dephault,
CUSTOMUI_DISK_ID,
ARB_REFCON);
Secondly, I see that in all the examples, each arbitrary parameter is followed by this code which I don't understand what it's for:
if (!err) {
PF_CustomUIInfo ci;
AEFX_CLR_STRUCT(ci);
ci.events = PF_CustomEFlag_EFFECT;
ci.comp_ui_width = 0;
ci.comp_ui_height = 0;
ci.comp_ui_alignment = PF_UIAlignment_NONE;
ci.layer_ui_width = 0;
ci.layer_ui_height = 0;
ci.layer_ui_alignment = PF_UIAlignment_NONE;
ci.preview_ui_width = 0;
ci.preview_ui_height = 0;
ci.layer_ui_alignment = PF_UIAlignment_NONE;
err = (*(in_data->inter.register_ui))(in_data->effect_ref, &ci);
}
If I have multiple arbitrary parameters, do I need multiple of the above following each one? Should these be unique for each unique arb?
In the HandleArbitrary function, it calls the arb handling functions using ARB_REFCON so that leads me to believe each arbitrary parameter must have their own unique ARB_REFCON. If that is the case then I need to call each of my custom parameters in the handler function? Something like this?
switch (extra->which_function) {
case PF_Arbitrary_NEW_FUNC:
if (extra->u.new_func_params.refconPV != ARB_REFCON) {
err = PF_Err_INTERNAL_STRUCT_DAMAGED;
}
else {
err = CreateDefaultArb(in_data,
out_data,
extra->u.new_func_params.arbPH);
}
break;
case PF_Arbitrary_NEW_FUNC:
if (extra->u.new_func_params.refconPV != ARB_REFCONTWO) {
err = PF_Err_INTERNAL_STRUCT_DAMAGED;
}
else {
err = CreateDefaultArb(in_data,
out_data,
extra->u.new_func_params.arbPH);
}
break;
...
Anyway, I have more questions but maybe this is enough for now. Basically, any guidance / tips and tricks on how to set up multiple arbitrary parameters is welcome!
Thanks!
1 Correct answer
sooo... arbs, eh? let's dive in.
conceptually, each arb param is kind of it's own thing, with it's own routines. when AE calls on an arb, it's up to you to tell which one it is, and envoke the correct handling code for that specific arb (unless they're all the same...).
the most basic method to do such routing would be a switch, calling for the function corresponding to that specific param.
switch(param_index) {
case ARB_1_INDEX:
ArbHandler1();
break;
case ARB_2_INDEX:
ArbHandler2
...Copy link to clipboard
Copied
sooo... arbs, eh? let's dive in.
conceptually, each arb param is kind of it's own thing, with it's own routines. when AE calls on an arb, it's up to you to tell which one it is, and envoke the correct handling code for that specific arb (unless they're all the same...).
the most basic method to do such routing would be a switch, calling for the function corresponding to that specific param.
switch(param_index) {
case ARB_1_INDEX:
ArbHandler1();
break;
case ARB_2_INDEX:
ArbHandler2();
break;
}
HOWEVER, if you intend to do a lot of plug-in developing, id suggest a less "C" approach and more of an automatic "C++" one.
enters "ARB_REFCON". what does it do? whatever you want it to do. whatever you put there will be passed along to the plug-in on arb calls FOR THAT SPECIFIC PARAM. meaning, it doesn't matter if it's NULL, if it's the same for all arbs or if it's different for each, AE is indifferent to that content. it's entirely up to you what to use it for.
so what do i suggest using it for? why for a specific handler, of course. ARB_REFCON if the size of a pointer, so go ahead and point to the correct handler. it can be a pointer to a function that handles that specific param, of an instance of a class doing the same, whatever you find suitable for your needs.
having done that, you now don't need to add each arb to the handling switch.
i personally went with classes, becasue all arbs must implement a bunch of stuff, some of which applies to most arb types i use (such as copying a value, or evaluating all values as equal because they're not quantitive). so i made a class handling some generic arb, and then override the specific methods i'd like to change. for me, that made a big time saver and decluttered a TON of code and switches...
in regeards to the default value passed on param declaration, that too need to be specific to that param's type. are your arbs all the same? using the same default is fine, BUT the handle should be different for each. so allocate a new handle for each arb param, even if the default value itself is different.
as for the PF_CustomUIInfo thingie, that only need to be done once per PARAM_SETUP call, and not per specific param. it doesn't necessarily have to do with arb params. if ANY of the effect's params have a custom UI in the ECW, or the plugin has a custom comp UI, it must be declared. if not, you can delete that bit of code entirely.

