Posts by hepi

BECOME PART OF THE COMMUNITY - Sign up here

    Ryan Kanarek
    Well, thinking about it now, it seems that Solution 1 is not that attractive, since I'd have to explicitly override ALL the Exec Config settings AND these "hard-coded?" height/width defaults for the keys.

    Do, it seems that, from a Plugin developer's perspective,
    every time the plugin needs to assign to an executor,
    it better switch the to it's own Exec Config temporarily,
    (Will need to generate such Exec Config)
    and restore to the original Exec Config afterwards.

    Do you see any better solution?

    Direct LUA
    One might think that using direct LUA (Accessing the object model directly, not using a Command Syntax at all)
    would be a good workaround here.
    But the issue is actually relevant only when the executor doesn't exist (prior to assigning a Sequence to it).
    And I've had bad experience trying to create Objects using LUA, I think it's not possible.

    Hi,

    When the selected Exec Config has, say, a Height of 2, then when assigning to an exec, the default Height=2 will be applied.

    I am trying to find a syntax that can override the Exec Config.
    I tried something like this but with no luck:
    Assign Seq X At Page 1.201 Property Height 1

    Of course I could workaround this by:

    Solution 1: Using 2 commands:
    Assign Seq X At Page 1.201

    Set Page 1.201 Property Height 1

    This raises another issue, since when setting height, it also resets the exec's key function (This might be a bug?)

    Solution 2:
    Temporarily selecting a different ExecConfig.
    This one seems just a bit of an overkill.


    I am just wondering if there is a way to do it with one command.

    Thanks,
    HEPi

    HI,

    When the selected Exec Config has, say, a Height of 2, then when assigning to an exec, the default Height=2 will be applied.

    I am trying to find a syntax that can override the Exec Config.
    I tried something like this but with no luck:
    Assign Seq X At Page 1.201 Property Height 1

    Of course I could workaround this by:

    Solution 1: Using 2 commands:
    Assign Seq X At Page 1.201

    Set Page 1.201 Property Height 1

    This raises another issue, since when setting height, it also resets the exec's key function (This might be a bug?)

    Solution 2:
    Temporarily selecting a different ExecConfig.


    I am just wondering if there is a way to do it with one command.

    Thanks,
    HEPi

    Andreas

    Hi,
    Do you know of any better workaround for a StartUp Event?

    I got reports from users who disabled the DMX Remote's "Enable Input" property, and now my plugins don't have a startup event 😵‍💫

    BTW: I remember a hack I experimented with that can achieve an independent StartUp event,
    but it requires changing the main UI LUA file of the system.
    .../MALightingTechnology/gma3_2.0.0/shared/resource/lib_menus/ui_onpc/onpc_ui.xml

    Andreas
    Hi,
    I am having difficulty storing a Recipe and setting an object-property on the same command.

    These work:
    Store Sequence 4 Cue 1 Part 0.1 Property Selection "13.13.1.5.1"

    Store Sequence 4 Cue 1 Part 0.1 Property Selection "ShowData.DataPools.Default.Groups.Spots1"

    Store Sequence 4 Cue 1 Part 0.1 Property "MAtricks" "#000000007e000892" (This is the HadleToStr() of the matrick object)


    These DON'T work - and there isn't any error
    Store Sequence 4 Cue 1 Part 0.1 Property Values "13.13.1.4.4.1"

    Store Sequence 4 Cue 1 Part 0.1 Property Values "ShowData.DataPools.Default.PresetPools.Color.W1"

    Store Sequence 4 Cue 1 Part 0.1 Property values "#0000000540000a67"

    These DON'T work - "Could not rersolve Object address"

    Store Sequence 4 Cue 1 Part 0.1 Property "MAtricks" "ShowData.DataPools.Default.MAtricks.T1"


    I am afraid there is some inconsistency here, or even a bug.
    I am particularly stuck with the "Values" property, it simply doesn't work.

    Any insight into this?

    Ahuramazda
    As I understand it,
    when making changes to a recipe,
    The root thread is triggered in order to update any dependents of this preset.

    My aim is to build a Preset with several Recipies as quickly as possible (under 100ms), adn launch a new cue that uses this Preset.
    I also need to Wait for that Preset to be "created" before I fire the Cue.
    I wanted to use a command, since I can do CmdIndirectWait, and make sure the cue is ready before I do "Go Cue X".
    So I tried to optimize the command to do as much as possible in one command, so I don't do a lot of sequential CmdIndirectWaits which take a lot of time (because of context switching I guess).

    ok.
    I tried it with direct LUA,
    it seems to work very fast,
    I just need to add a:
    CmdIndirectWait('Cook Preset X')

    In order to make sure it is cooked, since using direct LUA doesn't trigger an auto-cook.

    Thanks,
    HEPi


    - however feel free to send a feature request.

    Assign Group 1 + 2 At Preset 4.1.1 + 3 + 2

    Yep it will work in this specific case, and it is funny 😁

    I don't think I can use this solution for a generic case.
    For example, If I'm not mistaken, this could not be achieved:
    Recipe 1: Group 1
    Recipe 2: Group 1
    Recipe 3: Group 1
    Recipe 4: Group 2

    Because the "source" is only group 1 + 2, then it must be applied in a loop: 1,2,1,2,1,2,1,2,....
    And I think you can't use also multiple times the same target object since they are also collapsed.

    Hi,

    I just managed to finally create a thread safe event queue.
    I was struggling with this a few times and quit, and now I got it working.
    So excited as I am, I wanted to just share my solutions.

    (I'll be using the term thread and coroutine interchangeably)

    Background
    When your plugins start to go deeper, and you use Custom dialogs (Signals), Hooks, MIDI Remotes,
    you start to encounter a lot of multi-thread issues.
    Each event, from a Hook callback, Signal, MIDI Remote, is processed in a separate thread.

    For most of these events, it would be good enough if the plugin would process them sequentially in a "single thread" (same as a Web Browser).

    Solution Issues
    There are 2 limitations which makes creating a multi-thread solution difficult:

    1) No Resume Control: You don't have control over the coroutine which your LUA code runs in. Meaning for example, the coroutine that processes the main function of your plugin. You can do coroutine.yield but your don't have control over the resuming of this coroutine. You can just specify a "timeout" for the yield. (This is acceptable, I guess MA wanted to avoid coroutine from hanging)

    2) No API Access: If you create your own coroutine, then it doesn't have access to the ObjectAPI (or ObjectFree API).

    Mutex
    The first tool we need is a Mutex.
    This could be achieved by creating a coroutine, and using it hold the mutually exclusive lock-state.
    Each thread tries to lock the mutex, and if it is already locked,then the thread enter a yield loop, until the lock is released.

    EventQueue
    Now the mutex is good for short tasks, but if a mutex is locked for a long time, and many thread are in a yield loop, this is not so good. This could be CPU intensive, and we also could run out of threads.

    So an event queue is the solution.
    Now, we can't have a single work thread doing all th processing since we either [1] No Resume Control and [2] No API Access,
    then we need to have an alternating working thread to process the queue.
    The queue is easy to manage, we just use a Mutex when adding or removing from the queue.
    We need another Mutex to sync with whenever a thread checks if it could take the processing, or just add the event to the queue.

    The issue we encounter here, it that these 2 Mutexes (queue, processing-state) need to be unlocked together (atomically) when the processing thread empties the queue.

    So, the solution is actually to not use 2 Mutexes, but rather a single mutex to protect a state object that has both the queue and the processing state.

    It works.

    The code

    Well, unfortunately I write in Typescript, and use some of my own library tooling, so I don't have a pure LUA version to share right now.
    But I am attaching here my Typescript files for the Mutex and the EventQueue, so you could have a reference for it.

    The Use-Case
    Sometimes we want to optimize multiple commands into one command (to be faster)
    and instead of doing something like (That's assigning a group to a recipe line):
    Assign Group 1 At Preset 4.1.1

    Assign Group 2 At Preset 4.1.2

    Assign Group 3 At Preset 4.1.3

    We can do:
    Assign Group 1 + Group 2 + Group 3 At Preset 4.1.1 Thru 3

    The Issue
    If I want:
    Recipe 1: Group 1
    Recipe 2: Group 1
    Recipe 3: Group 2

    Then we hit an issue, if I do:
    Assign Group 1 + Group 1 + Group 2 At Preset 4.1.1 Thru 3

    We get:
    Recipe 1: Group 1
    Recipe 2: Group 2
    Recipe 3: Group 1

    This is because (my guess) MA syntax is collapsing the Group 1 + Group 1 to one object,
    so it's applying 2 object (Group 1 and Group 2) to a destination of 3 objects. (Using repeat logic: 1,2,1,2,1,2....)

    - Can anyone think of a workaround?
    - Is this a bug that needs to be reported?

    Andreas

    Thanks,
    HEPi

    Hi,

    In version 2.0.0.4 MA changes the bpm values of a SpeedMaster.
    I am looking for the formula to get bpm from the fader value:
    faderValue : 0-100
    bpm: 0-225

    Has anyone cracked it yet?

    Oh, or if there is another way to get a SpeedMaster's BPM value (without the fader vlaue), that would be good as well.

    In version 1.9.x
    The range was different, and the formula was:
    bpm = 240* (faderValue / 100)^2

    Thanks,
    HEPi

    Ahuramazda
    Hi,

    Just wanted to let you know that I am releasing very soon the Playback Grid plugin,
    which is a generic Grid generator (Color, Position,....) and MORE.

    It has some cool features:
    - Scenes (like your Favorites): Scene buttons with automatic thumbnails
    - Sub-Grouping (choosing multiple presets (colors) for the same group, resulting in say, Odd/Even colors)
    - Hold: make multiple grid selections, and then launch all of them at once.
    - Transitions: 10 transition "presets" with on-the-fly editing.

    So it's quite a powerful plugin.
    There is one BIG advantage that your plugin has, which is that it is FREE 😉

    If you want to get a BETA version to play with, you are welcome to contact me at:
    hepi@ma3-pro-plugins

    HEPi