SequenceMgr.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. /*
  2. SEQUENCE GROUPING MANAGEMENT MODULE
  3. this module builds a representation of a sequence in values using containers
  4. It allows to create groups of keys, a group being a cue and one key per layer.
  5. In a group, all keys sync their time on cue's time, only value can be modified
  6. The sequence with grouping can then be exported and reloaded.
  7. The module checks periodicaly if timeline sequence structure (cues, layers and keys) and
  8. module values structure are in sync. If out of sync, you may either rebuild values structure
  9. from sequence or rebuild sequence from values
  10. */
  11. var syncRate = 10;
  12. var synchronize = false ;
  13. var debug = true;
  14. var debugFile;
  15. var parametersPath = local.parameters ;
  16. var sequence ;
  17. var sequencePath = local.parameters.sequence ;
  18. var file ;
  19. var filePath = local.parameters.sequenceFile ;
  20. var newGroup = local.values.newGroup ;
  21. var groups = local.value.groups ;
  22. var cues = local.keys.cues ;
  23. var layers = local.keys.layers ;
  24. var rebuildValues = script.addTrigger("rebuild values", "adds a key at current cursor position" );
  25. var refreshKeys = script.addTrigger("refresh keys", "truc");
  26. var printKeys = script.addTrigger("printKeys","truc");
  27. var clearSeq = script.addTrigger("clear Sequence","truc");
  28. var sequence_structure = { params: {},
  29. groups:{},
  30. keys:{
  31. cues:{},
  32. layers:{}
  33. }
  34. };
  35. //WAS tl_groups
  36. /*group0 : { inCue : {pan : "key", tilt : "key", zoom : "key", dim : "key", focus : "key"},
  37. outCue : {pan : "key", tilt : "key", zoom : "key", dim : "key", focus : "key"}
  38. }*/
  39. ///////////////////// SCRIPT FUNCTIONS //////////////////////////////
  40. function init() {
  41. script.log("LOADED SEQUENCE GROUPING MANAGEMENT MODULE ");
  42. //adapt update rate
  43. updateSyncRate();
  44. //test if a sequence is already choosen else refresh and unlock sequence enum
  45. sequence = sequencePath.getKey();
  46. if(sequence == ""){refreshSequenceEnum();}
  47. else{sequencePath.setAttribute("readonly", true);}
  48. }
  49. function scriptParameterChanged(param){
  50. if (param.is(printKeys) ){printKeys();}
  51. else if(param.is(rebuildValues)){rebuildValuesStructure();}
  52. else if (param.is(refreshKeys)){
  53. script.log("refreshKeys");
  54. refreshKeysList();
  55. }
  56. else if (param.is(clearSeq)){seq_clearSequence();}
  57. else {script.log("scriptparamchanged" + param.name);}
  58. }
  59. var syncDelta = 0.;
  60. function update(deltaTime){
  61. if(synchronize){
  62. syncDelta += deltaTime ;
  63. if (syncDelta > syncRate){
  64. syncDelta = 0. ;
  65. // if (debug ){
  66. // // script.log(debugFile.getAbsolutePath());
  67. // debugFile.writeFile(JSON.stringify(sequence_structure), true);
  68. // }
  69. // refreshKeysList();
  70. struct_buildValuesFromSeq();
  71. }
  72. }
  73. }
  74. /////////////////////////// HELPERS /////////////////////////////////
  75. function printMethodsAndProperties(obj){
  76. script.log(" ");
  77. // var name = obj.getControlAddress() == undefined ? "object" : obj.getControlAddress();
  78. var name = "object";
  79. script.log(" METHODS OF " + name);
  80. var methods = util.getObjectMethods(obj);
  81. for(var i=0 ; i<methods.length ; i++){
  82. script.log(" "+ methods[i]);
  83. }
  84. script.log(" PARAMETERS OF " + name);
  85. var props = util.getObjectProperties(obj, true, false);
  86. for(var i=0 ; i<props.length ; i++){
  87. script.log(" "+ props[i]);
  88. }
  89. script.log(" OBJECTS OF " + name);
  90. var props = util.getObjectProperties(obj, false, true);
  91. for(var i=0 ; i<props.length ; i++){
  92. script.log(" "+ props[i]);
  93. }
  94. }
  95. function printKeys(){
  96. var seq = root.sequences.sequence.layers.mapping.automation.getItems() ;
  97. if(seq.length){
  98. for(var i=0; i<seq.length; i++){
  99. script.log (">> "+seq[i].name + " " + seq[i].position.get() + " " + seq[i].listSize.get() );
  100. }
  101. }
  102. else{script.log("nothing to print");}
  103. }
  104. /////////////////////// PARAMETERS FUNCTIONS ///////////////////////
  105. // Module callback
  106. function moduleParameterChanged(param){
  107. if (param.is(parametersPath.importExport.sequenceFile)) {}
  108. else if (param.is(parametersPath.importExport.loadSequence)){loadSequenceFile();}
  109. else if (param.is(parametersPath.importExport.exportSequence)) { exportSequenceFile();}
  110. else if (param.is(parametersPath.synchronize)){}
  111. else if (param.is(parametersPath.syncRate)){updateSyncRate();}
  112. else if (param.is(parametersPath.changeSequence)){refreshSequenceEnum();}
  113. else if (param.is(parametersPath.sequence)){
  114. sequence = sequencePath.getKey();
  115. script.log("watching "+ sequence);
  116. }
  117. else{script.log("received module param :" + param.name);}
  118. }
  119. function updateSyncRate(){
  120. syncRate = parametersPath.syncRate.get();
  121. script.log("new sync rate : " + syncRate);
  122. script.setUpdateRate(syncRate);
  123. }
  124. //refresh Enum
  125. function refreshSequenceEnum(){
  126. script.log("refresh list of sequences");
  127. local.parameters.sequence.setAttribute("readonly",false);
  128. if(root.sequences.getItems().length){
  129. local.parameters.sequence.removeOptions();
  130. for(var i=0 ; i<root.sequences.getItems().length ; i++ ){
  131. local.parameters.sequence.addOption(root.sequences.getItems()[i].name,i);
  132. }
  133. }
  134. }
  135. function testSequenceFile(){
  136. var file = local.parameters.sequenceFile;
  137. //test if a file is declared
  138. if( file.getAbsolutePath() != ""){
  139. script.log("testing file " + file.getAbsolutePath() );
  140. var data = file.readFile(true);
  141. // test if expected fields are absent
  142. if (data.groups == undefined){
  143. script.log("file structure not recognized");
  144. refreshSequenceEnum();
  145. }
  146. //if all is well, let's load in sequence_structure
  147. else {
  148. script.log("ready to import");
  149. return 1;
  150. // loadSequenceFile();
  151. }
  152. }
  153. else {
  154. script.log("no file to load");
  155. refreshSequenceEnum();
  156. return 0;
  157. }
  158. }
  159. function loadSequenceFile(){
  160. script.log("loading file");
  161. sequence_structure = local.parameters.sequenceFile.readFile(true);
  162. //lock enum with curent sequence name
  163. var sequenceList = local.parameters.sequence;
  164. sequenceList.removeOptions();
  165. sequenceList.addOption(sequence_structure.params.sequence, 0);
  166. local.parameters.sequence.setAttribute("readonly",true);
  167. }
  168. function exportSequenceFile(){
  169. script.log("exporting file");
  170. local.parameters.sequenceFile.writeFile(JSON.stringify(sequence_structure), true);
  171. }
  172. /////////////////////// VALUES FUNCTIONS ///////////////////////
  173. /* Values hold all keys, presented in group containers
  174. a nogroup container shows keys that are not grouped
  175. */
  176. // Value callback
  177. function moduleValueChanged(value){
  178. if (value.name == "addGroup"){createNewGroup(sequence_structure.params.sequence);}
  179. }
  180. //check if sequence and value structures are in sync (same cues, layers, and keys)
  181. function struct_checkSync(){
  182. }
  183. //rebuild values.keys structure from sequence
  184. function struct_buildValuesFromSeq(){
  185. //build cues
  186. //build layers
  187. //build keys in layers
  188. }
  189. function struct_exportToFile(){}
  190. function rebuildValuesStructure() {
  191. script.log("updating values structure");
  192. //empty current structure
  193. // local.values.removeAll();
  194. local.getChild("Values").removeContainer("newGroup");
  195. local.getChild("Values").removeContainer("groups");
  196. local.getChild("Values").removeContainer("ungrouped");
  197. //rebuild containers
  198. var ng_cont = local.values.addContainer("New group");
  199. var g_cont = local.values.addContainer("groups");
  200. var ug_cont = local.values.addContainer("ungrouped");
  201. // rebuild new group
  202. ng_cont.addTrigger("add group", "adds a new group at cursor time with below values");
  203. ng_cont.addFloatParameter("group time", "time position where the group will be created ", 0., 0.);
  204. var layer_cont = ng_cont.addContainer("layers values");
  205. var layers = util.getObjectProperties(sequence_structure.keys.layers) ;
  206. for (var i=0; i<layers.length; i++){
  207. //add a float value in each layer for group creation
  208. layer_cont.addFloatParameter(layers[i], "", 0., 0., 1.);
  209. ug_cont.addContainer(layers[i]);
  210. }
  211. //rebuild keys grouped/ungrouped
  212. //first create group containers in groups
  213. // //then create layer containers in ungrouped
  214. // var layer_cont = ug_cont.addContainer("layers values");
  215. }
  216. /////////////////////// TIMELINE FUNCTIONS ///////////////////////
  217. function seq_clearSequence(){
  218. var sequence = root.sequences.getItemWithName(sequence_structure.params.sequence) ;
  219. script.log("clearing all keys and cues of sequence : "+sequence.name);
  220. sequence.cues.removeAll();
  221. var layers = sequence.layers.getItems();
  222. if(layers.length){
  223. for (var i = 0; i<layers.length; i++){
  224. layers[i].automation.removeAll();
  225. }
  226. }
  227. }
  228. //use Values structure to rebuild the sequence
  229. function seq_buildSeqFromValues(){}
  230. //use file to rebuild sequence
  231. function seq_buildSeqFromFile(){}
  232. function refreshKeysList(){
  233. var sequence = root.sequences.getItemWithName(sequence_structure.params.sequence);
  234. var cues = sequence.cues.getItems();
  235. sequence_structure.keys.cues = {};
  236. if(cues.length){
  237. for (var i = 0 ; i < cues.length ; i++){
  238. sequence_structure.keys.cues['cue'+i] = {index : i};
  239. sequence_structure.keys['cues']['cue'+i]['name'] = cues[i].name;
  240. sequence_structure.keys['cues']['cue'+i]['niceName'] = cues[i].niceName;
  241. sequence_structure.keys['cues']['cue'+i]['time'] = cues[i].time.get();
  242. // script.log(tl_keyframes['cues']['cue'+i].time);
  243. }
  244. }
  245. var layers = sequence.layers.getItems();
  246. sequence_structure.keys.layers={};
  247. if(layers.length){
  248. for (var i = 0 ; i < layers.length ; i++){
  249. sequence_structure['keys']['layers'][layers[i].name] = {};
  250. // script.log(currentLayer.name);
  251. if(layers[i].automation.getItems().length){
  252. // script.log(currentLayer.automation.items.length);
  253. for (var j = 0 ; j < layers[i].automation.getItems().length ; j++){
  254. var currentkey = layers[i].automation.getItems()[j] ;
  255. sequence_structure['keys']['layers'][layers[i].name][currentkey.name] = {
  256. position : currentkey.position.get(),
  257. value : currentkey.value.get(),
  258. name : currentkey.name,
  259. niceName : currentkey.niceName,
  260. //la propriete "group" est écrite
  261. group : currentkey.group
  262. // group : currentkey.hasChild("group") != undefined ? currentkey.group.get() : "ungrouped"
  263. };
  264. // script.log(tl_keyframes['keys'][currentLayer.name][currentkey.name].value);
  265. }
  266. }
  267. }
  268. }
  269. // myFile.writeFile(JSON.stringify(tl_keyframes), 1);
  270. }
  271. // function writeKeyGroup(){
  272. // var groups = sequence_structure.groups
  273. // }
  274. function createNewGroup(seqName){
  275. //create a cue and a key in each layer at cursor position in selected sequence
  276. var groupIndex = util.getObjectProperties(sequence_structure.groups) ;
  277. script.log(groupIndex.length);
  278. // printMethodsAndProperties(groupIndex);
  279. var seq = root.sequences.getItemWithName(seqName);
  280. var currentTime = seq.currentTime.get() ;
  281. // var currentTime = local.values.newGroup.groupTime.get();
  282. script.log(currentTime);
  283. newCue = seq.cues.addItem();
  284. newCue.time.set(currentTime);
  285. var layers = seq.layers.getItems();
  286. script.log(layers.length);
  287. // var struc_layers = util.getObjectProperties(sequence_structure.keys.layers);
  288. if(layers.length){
  289. for(var i=0;i<layers.length; i++ ){
  290. // script.log(sequence_structure.keys.layers[layers[i].name]);
  291. newKey = layers[i].automation.addItem();
  292. newKey.position.set(currentTime);
  293. script.log(local.values.newGroup.layersValues[layers[i].name].get());
  294. newKey.value.set(local.values.newGroup.layersValues[layers[i].name].get());
  295. newKey.addStringParameter("group", "key is part of this group","mongroupe");
  296. layers[i].automation.reorderItems();
  297. }
  298. }
  299. // seq = seq.getItems();
  300. }