Custom Action с функцией State возможно?

Aleksandr Oleynik

Well-Known Member
16 Янв 2007
26.360
19.919
113
62
Киев
Нужно сделать Кастом Экшн который бы имел атрибут on/off - как, например многие Акшны SWS.
Это вообще возможно?
Если нет, то как объединить два Экшна под одной кнопкой, чтоб кнопка реагировала на состояние on/off одного из них - чтоб было видно нажата она или отжата - ну вот как с Action -ом Exclusive toggle
 
Последнее редактирование модератором:
Если правильно понял,видел подобное в скрипте для квантайза аудио по стретч маркерам.Там используется цикл-экшн с If-ом и Exclusive Toggle.
То есть если Exclusive toggle включен,работает один скрипт,если нет,то по If-у в цикл-экшне переходит на другой скрипт.Типа так.
 
Не, не правильно понял!
Мне нужно чтобы Кастом Экшин сам выдавал своё состояние - включен-выключен, естественно если в нём есть работающий Toggle.
 
Не знаю, подойдёт ли вам такой метод, но попробовать так: сделать экшн, закинуть его на кнопку, а на кнопку кликнуть правой клавишей мыши.
 
@Aleksandr Oleynik , он-то как раз при этом и запускается - только что проверил.
Скрипты не запускаются ...., тоже проверил.
Мне нужно видеть состояние Скрипта повешенного на кнопку - запущен он или нет.@@Michael, вроде вот подсказал как это можно сделать -
но теперь же эту подсказку нужно научиться реализовать :(
[DOUBLEPOST=1436420554,1436386009][/DOUBLEPOST]
SetToggleCommandState + RefreshToolbar2 изменяет toggle state.
Михаил, самостоятельные пробы и поиски КАК, пока без результата.... :(
Напишите пример кода, который должен быть в скрипте, чтобы потом работала кнопка как ON/OFF и было видно когда скрипт запущен, а когда остановлен.
Скрипт, понятное дело с постоянным (пока пользователь не остановил скрипт) defer - ом.
Сейчас крайне не удобно за этим следить - определить запущен ли скрипт можно только после повторной попытки его запустить.

На поверхности несколько вопросов -
1. SetToggleCommandState(int section_id, int command_id, int state)
Что тут писать в section_id ? Где его брать?
Это - Main, MIDI Editor видимо, но какие у них ID?
2. Эта команда, на сколько я понимаю меняет состояние Acton у которых есть параметр State и в купе с RefreshToolbar2 я увижу изменение состояния ЭТОГО Action на Тулбаре.
Но я то хочу менять состояние State самого скрипта - чтоб нажав на его кнопку в Тулбаре было видно, что она нажата и что скрипт запущен.

Получается что нужно ставить две кнопки рядом?

PS: Прошу прощения, пишу быстрее чем думаю :(
Разобрался - state задавать можно самому скрипту.
И это работает.
Одна беда - теперь при нажатии кнопки Скрипта она остаётся нажатой и видно что Скрипт заработал. Но вот как её теперь отжать (погасить) при повторном нажатии кнопки?
Как остановить работу скрипта при повторном нажатии кнопки понятно - запомнить Terminate instances и всё.
 
Последнее редактирование:
@Aleksandr Oleynik,
PHP:
get_action_context(#fn, sec, cmd);
state = GetToggleCommandStateEx(sec, cmd);//Current State
SetToggleCommandState(sec, cmd, state <= 0 ? 1 : 0);//Change State (ON/OFF)
RefreshToolbar2(sec, cmd);
Тут один момент,чтоб скрипт работал от кнопки,нужно закрыть окно с кодом(не знаю почему)
123.gif
 
  • Like
Реакции: Aleksandr Oleynik
@EUGEN27771, спасибо!
Не уверен, что это в моём случае (когда Скрипт с вечным defer, пока его не остановит пользователь) будет работать (мне ведь нужно сделать, чтобы когда я нажимаю кнопку - скрипт запускался и кнопка загоралась, а когда второй раз на кнопку тыкаю - скрипт останавливался и кнопка тухла). Проверил - естественно не работает.
НО!!!!!, точно в значении переменной можно писать выражение - для меня это очень важное открытие - спасибо!
 
Последнее редактирование:
@@Michael, Мне ведь не toggle state нужен а запущен скрипт или нет.
Мне не нужно чтоб кнопка и статус скрипта менялся при каждом его включении, мне нужно чтобы статус запущеннго скрипта был ON, а остановленного - OFF.
И на сколько я понимаю, отловить САМИМ скриптом момент его выключения, отправить команду на изменения статуса, а потом закрыться - не возможно?
Или возможно?

PS: За Section_Id - @@Michael, @EUGEN27771, Спасибо
 
Код:
value = GetProjExtState(key, value)
value == 1 ? (  // если скрипт уже запущен
   condition = 0 // создаём условие для отключения
   ) : (
   condition = 1 // создаём условие для включения в противном случае
);


function script()  (
  condition == 1 ? (
    ...какие-то действия...
    SetToggleState (0,имяскрипта, 1)
    SetProjExtState(key, value, 1)
    RefreshToolbar2(0, имяскрипта)
    defer(script)
  ) : (
   atexit(
      SetToggleState (0,имяскрипта, 0);
      SetProjExtState(key, value, 0)
      RefreshToolbar2(0, имяскрипта)
    ); // закрываем atexit
  ); //  закрываем condition == 1 ?
); //  закрываем  function script()

script()

Мне не нужно чтоб кнопка и статус скрипта менялся при каждом его включении
В этом случае уберите из скрипта верхний кусок и задайте condition = 1 при включении.
 
Последнее редактирование:
  • Like
Реакции: Aleksandr Oleynik
Михаил, т.е., если у меня есть уже написанный скрипт с вечным defer (он должен постоянно, пока проект запущен следить за состоянием проекта и соответственно реагировать)
То я просто весь код помещаю вместо вашего -
...какие-то действия...

Так?
Или нужно переделывать логику скрипта?
 
Какой тогда вобще смысл в этом треде, если вы хотите получить информацию о том, запущен ли скрипт при том, что он у вас всегда запущен?
 
Какой тогда вобще смысл в этом треде, если вы хотите получить информацию о том, запущен ли скрипт при том, что он у вас всегда запущен?
Я вас сбил этой своей фразой -
(он должен постоянно, пока проект запущен следить за состоянием проекта и соответственно реагировать)
Не, он не всегда запущен, он не останавливается ни по какому действию, кроме команды пользователя -
На кнопку нажал - скрипт запустился и работает всё время и следит за проектом, пока пользователь не нажал повторно на кнопку -
нажал повторно - тогда скрипт остановился.
И вот состояние скрипта - работает или остановился, я и хочу видеть на кнопке.
 
Не работает :(
Я помарки вроде все поправил, сделал простенький тестовый скрипт, который убирает громкость в мин бесконечность, если её выставили в 0 dB, но он виснет на atexit-е
Убираю "" вокруг кода в atexit -е ---- работает, но atexit не срабатывает.

PHP:
value = GetProjExtState(0, key, value, #valOutNeedBig);
value == 1 ? (  // если скрипт уже запущен
   condition = 0 // создаём условие для отключения
   ) : (
   condition = 1 // создаём условие для включения в противном случае
);



function script()
(
  condition == 1 ? (   

    tr = GetTrack(0, 0);
    GetTrackUIVolPan(tr, vol, pan);
    vol == 1 ?
    (
    SetMediaTrackInfo_Value(tr, "D_VOL", 0);
    );

   
    SetToggleCommandState(0, NamedCommandLookup("_a1949fffb81e0244b9596a8391f07f2e"), 1);
    SetProjExtState(0, key, value, 1);
    RefreshToolbar2(0, NamedCommandLookup("_a1949fffb81e0244b9596a8391f07f2e"));
    defer("script()");
  ) : (
   atexit("
    SetToggleCommandState(0, NamedCommandLookup("_a1949fffb81e0244b9596a8391f07f2e"), 0);
    SetProjExtState(0, key, value, 0);
    RefreshToolbar2(0, NamedCommandLookup("_a1949fffb81e0244b9596a8391f07f2e"));"
    ); // закрываем atexit
  ); //  закрываем condition == 1 ?
); //  закрываем  function script()

script();
 
Вместо key, value везде написать в кавычках - "Toggle_script", "Value"?
Не, не работает Виснет на первой строке после atexit("
 
Код:
script_id = NamedCommandLookup("_1a555e86962e65429a52a7e279147112" );

toggle_state = GetToggleCommandStateEx(0, script_id);
toggle_state == -1 ? toggle_state = 0 ;
toggle_state == 1 ? (
   toggle_state = 0
  ) : (
   toggle_state = 1
);

function code() (
  tr = GetTrack(0, 0);
  GetTrackUIVolPan(tr, vol, pan);
  vol == 1 ?
    (SetMediaTrackInfo_Value(tr, "D_VOL", 0);
  );
);

function exit() (
  SetToggleCommandState(0, script_id, 0);
  SetProjExtState(0, "ToggleState", "01", 0) ;
  RefreshToolbar2(0,script_id);
);

function script()
(
toggle_state == 1 ? (
    code()  ;
    SetToggleCommandState(0, script_id, 1);
    SetProjExtState(0, "ToggleState", "01", 1);
    RefreshToolbar2(0,script_id);
    defer("script()");
  ) : (
   atexit("exit()");
  );
);

script();
 
Последнее редактирование:
Какая-то ошибка синтаксиса написания выражения внутри скобок atexit
Пробую по разному в простом тестовом скрипте - не пашет и всё тут, выдаёт ошибку на atexit-е

PHP:
function wait_par()
(
    tr = GetTrack(0, 0);
    TrackFX_GetParam(tr, 0, 0, min, max) != 100 ?
    (
    SetMediaTrackInfo_Value(tr, "D_VOL", 0);
    defer("wait_par()");
    ):(
        atexit(
        SetMediaTrackInfo_Value(tr, "D_VOL", 1);
        );
);
);
wait_par();

В таком виде прекрасно работает -

PHP:
function wait_par()
(
    tr = GetTrack(0, 0);
    TrackFX_GetParam(tr, 0, 0, min, max) != 100 ?
    (
    SetMediaTrackInfo_Value(tr, "D_VOL", 0);
    defer("wait_par()");
    ):(
        atexit("");
        );
);
);
wait_par();

С выражением внутри "" - ни как не хочет

PS: Пока писал вы уже ответили новым скриптом.
Но всё-же, что не так с выражением внутри "" в atexit-а?
Или, судя по вашему скрипту, внутри atexit-а может быть только функция?
 
Всё подряд опять мешаете. Одни defer внутри других, условия, всё в кучу. Вам действительно нужна такая хитровыдуманная логика? Может проще часть процессов людям оставить?
 
Вам действительно нужна такая хитровыдуманная логика?
Так это она по факту такая выходит.
Я хочу сделать примитивную (казалось бы) вещь - на Тулбаре кнопку,
которая бы загоралась, когда на неё Пользователь тыкает - запускала скрипт с "следящим за процессами" defer-ом.
А когда Пользователю эта слежка не нужна и скрипт нужно отключить - он на кнопку нажал, она потухла, скрипт прекратил работать.
Для каких-то конкретных ситуаций можно конечно сделать чтоб скрипт при наступлении какого-то события сам себя выключал.
Но можно ли тогда автоматом кнопку отключить?
[DOUBLEPOST=1436451531,1436451474][/DOUBLEPOST]Кстати, ваш последний скрипт ПОЧТИ как нужно работает.
Почти, потому как для выключения кнопки (чтоб она потухла), на неё нужно два раза нажимать.
Может можно допилить?

PS: И всё-таки, хотелось бы разобраться с кодом внутри atexit -
какой он может быть?

PSS: В любом случае - с вашей помошью я вот человеку жизнь упрощю с инсталяцией фичи запускающей синхронно Play при поступлении на вход треков с миди клавы Нот.
 
Последнее редактирование:
Путём многих вариаций скрипта выше (в eel и lua) пришёл к выводу, что
1) toggle state некорректно отображается в экшнах (статус изменяется только после изменений в сортировке экшнов в листе), возможно это повод усомниться в работоспособности RefreshToolbar2 непосредственно в тулбаре,
2) SetToggleCommandState непредсказуем внутри работающего defer как для скрипта, внутри которого он находится, так и для обычных toggle экшнов.

Дружно ищем косяки в моём скрипте (уверен, они есть) и, если находим, багрепортим в трекер кокоса. Или сюда по крайней мере.
 
@@Michael, так скрипт работает правильно! Логика его мне сейчас понятна и она совершенно верная!
Тут не верно работает кнопка - она не отжимается изменившимся в скрипте статусом и её приходится ещё раз нажимать, чтоб отжалась уже при не работающем скрипте.
1) toggle state некорректно отображается в экшнах (статус изменяется только после изменений в сортировке экшнов в листе), возможно это повод усомниться в работоспособности RefreshToolbar2 непосредственно в тулбаре,
А в Action list всегда статус рефрешился только рефрешем самого листа.
Думаю RefreshToolbar2 тут не при чём. Он для Тулбара.

Я конечно ещё раз всё внимательно проверю.....
 
Последнее редактирование:
@@Michael, я с таким поведением встречался,некоторые скрипты вообще работают только после перезагрузки,если там деферы и на кнопки тулбара завязано что-либо.Возможно это нормально,что некоторые связки в программе не могут обновляться сразу.
 
Видимо в таких случаях лучше делать стартующий при старте проекта скрипт и Взводящий и Тушащий нужную функцию скрипта Action с функцией on/off - как собственно я изначально и сделал.

PS: И всё таки, Парни, растолкуйте про atexit("");
как и какие в нём писать команды (коды), чтоб он работал?

Например вот этот скрипт запускает Play (action id = 1007) только после того как принудительно скрипт остановить -

PHP:
function exit() (
  Main_OnCommand(1007, 0);
);


function wait_par()
(
    tr = GetTrack(0, 0);
    TrackFX_GetParam(tr, 0, 0, min, max) != 100 ?
    (
    SetMediaTrackInfo_Value(tr, "D_VOL", 0);
   
    ):(
        atexit("exit()");
);
defer("wait_par()");
);
wait_par();
 
Последнее редактирование:
@Aleksandr Oleynik, как я понимаю,atexit вызывает указанную
функцию по завершению программы.Короче,как бы действие напоследок,перед самым выходом,окончанием.Но это чисто интуитивно,может все и не так.
Например вот этот скрипт запускает Play (action id = 1007) только после того как принудительно скрипт остановить
ну собственно,подтверждает предположение,скрипт останавливается и напоследок выполняется функция,указанная в atexit
 
@EUGEN27771, очень похоже на то!
Только вот в первой версии скрипта Михаила мне так и не удалось заставить вообще работать atexit с кодом внутри, тупо выдавал ошибку именно на atexit-e.
И я хотел бы понять в чём проблема, что с частью команд внутри скобок atexit он работать не хочет.
Хотя там может в другом проблема.
У меня похожие проблемы возникают периодически с применением atexit, вот я и решил разобраться с этим как-то по подробнее.
[DOUBLEPOST=1436509306,1436508439][/DOUBLEPOST]Ну вот в моём сообщении, в примерах, тоже не понятка -
http://rmmedia.ru/threads/117697/#post-1900140
 
@Aleksandr Oleynik, проблемы могут быть с расположением функции в коде,например.фунция не определена еще,а уже вызвана.

Ну вот в моём сообщении, в примерах, тоже не понятка -
Вызывать в этэксит,наверное,можно только фукцию,то есть определить выражение
SetMediaTrackInfo_Value(tr, "D_VOL", 1); как функцию function() имя-рек,я не проверял,просто предполагаю.
 
Да вот как-то без системно и по разному!
Я тоже так подумал, когда функция заработала, но у меня есть куча примеров когда работает и выражение.
По этому и каша в башке....
Толи баг, толи фича
 

Сейчас просматривают