1 /**
  2     xUIにタスクコントローラを設けてバックグラウンド処理をコントロールする
  3     以下のプロパティを新設
  4 
  5  ■□◀▶◇◆①
  6     
  7 */
  8 
  9 var startupTaskController=function(){
 10         xUI.player = {};
 11     xUI.player.startClick = (new Date()).getTime();
 12     xUI.player.stopClick  = xUI.player.startClick;
 13     xUI.player.status     = 'stop';
 14     xUI.player.loop       = false;
 15     xUI.player.standbyStart = true;
 16     xUI.player.wait       = 0;
 17     xUI.player.keyboard	  = false;
 18     xUI.player.markSwap   = false
 19     xUI.player.waitCount  = 0;
 20     xUI.player.countStack = [];
 21     xUI.player.countAnimation=['■■■■#■■■■','□■■■#■■■■','□□■■#■■■■','□□□■#■■■■','□□□□#■■■■','□□□□#□■■■','□□□□#□□■■','□□□□#□□□■','□□□□#□□□□','====③====','====②====','ーーーー◆ーーーー']
 22     
 23     xUI.player.start = function(withMark,clickClock){
 24         xUI.player.startClick = (new Date()).getTime();
 25         if(clickClock)xUI.player.startClick =clickClock;
 26 //        waitClocks = (isNaN(waitClocks))? 0:parseInt(waitClocks);
 27         xUI.selectBackup      = xUI.Select.slice();
 28         xUI.selectionBackup   = xUI.Selection.slice();
 29         xUI.selection();//バックアップとってクリア
 30         xUI.player.waitCount     = parseInt(xUI.player.wait);
 31         xUI.player.currentFrame  = 0 ;//処理中のフレーム
 32         if(withMark){
 33 //	        xUI.player.markFrame(document.getElementById(xUI.Select.join('_')));
 34 	        xUI.player.markFrame(xUI.Select);
 35 //            xUI.player.countStack.push(xUI.Select);
 36             xUI.player.getCount      = true  ;//フレーム取得フラグセット
 37         }else{
 38             xUI.player.getCount      = false ;//フレーム取得フラグリセット
 39         }
 40 //        xUI.player.countStack    = [];//スタート時点の自動クリアを行わない 明示的なクリアまでマークと共に保持する
 41         xUI.player.status        = 'run';
 42     };
 43     xUI.player.stop      = function(clickClock){
 44         xUI.player.stopClick = (new Date()).getTime();
 45         xUI.player.status   = 'stop';
 46         if(clickClock)xUI.player.stopClick =clickClock;
 47         xUI.selection(add(xUI.Select,xUI.selectionBackup));
 48         if(this.waitCount !=0 ){ this.waitCount=0;if(document.getElementById("timerDisplay").innerHTML) document.getElementById("timerDisplay").innerHTML='';}
 49     };
 50 /** ストップウオッチ機能のための補助機能
 51 
 52 */
 53 /**
 54  *    セルにマーカーを配置してマークをスタックする
 55  */
 56 xUI.player.markFrame=function(element){
 57     if(element instanceof Array){
 58         this.countStack.push(element);
 59         element=document.getElementById(element.join('_'))
 60     }else{
 61         this.countStack.push(element.id.split('_'));
 62     }
 63     nas.HTML.addClass(element,"trackMarker");
 64 }
 65 /**
 66  *    セルマーカー及びスタックをクリア
 67  */
 68 xUI.player.clearMark=function(){
 69     (function(){
 70         for (var trk = 0 ;trk < xUI.XPS.xpsTracks.length ; trk++){
 71             for (var frm = 0 ;frm < xUI.XPS.xpsTracks[0].length ; frm++){
 72                 var cell = document.getElementById([trk,frm].join('_'));
 73                 nas.HTML.removeClass(cell,"trackMarker");
 74 //                if(cell.classList.contains('trackMarker')) cell.classList.remove('trackMarker');
 75             }
 76         }
 77     })();
 78     xUI.player.countStack=[];
 79 }
 80 /**
 81  *    
 82  */
 83 xUI.player.buildCount=function(trackID){
 84     var currentFrame = xUI.Select[1];
 85     var targetTrack = xUI.XPS.xpsTracks[xUI.Select[0]];
 86     var buidTarget=new Array(xUI.XPS.xpsTracks.length);
 87     for (idx=0;idx < buidTarget.length;idx++){buidTarget[idx]=[];}    
 88 //マークをソート
 89     xUI.player.countStack.sort(function(a,b){
 90         if (a[0] < b[0]) return -1
 91         else if (a[0] > b[0]) return 1
 92         else if (a[1] < b[1]) return -1
 93         else if (a[1] > b[1]) return 1
 94         return 0;
 95     });
 96 //重複マークを削除してトラック別にソート
 97     var currentMark=[null,null];
 98     for (var cix = 0 ; cix < xUI.player.countStack.length ;cix ++){
 99         if((xUI.player.countStack[cix][0]==currentMark[0])&&(xUI.player.countStack[cix][1]==currentMark[1])) continue;
100          buidTarget[xUI.player.countStack[cix][0]].push(xUI.player.countStack[cix][1]);
101          currentMark=xUI.player.countStack[cix];
102     }
103 //ターゲットトラックを区間パース
104     var buildSections=[{
105         startFrame:0,
106         duration:0,
107         value:false
108     }];
109     var currentSection = buildSections[0];
110     if(buidTarget[xUI.Select[0]].length==0){
111         currentSection.duration=targetTrack.length;
112     }else{
113         if (buidTarget[xUI.Select[0]][0] != 0){
114             currentSection.value = false;
115             currentSection.duration = buidTarget[xUI.Select[0]][0];
116             currentSection = buildSections[ buildSections.push({
117                 startFrame:buidTarget[xUI.Select[0]][0],
118                 duration:1,
119                 value:true
120             })-1];
121         }else{
122             currentSection.value = true;
123             currentSection.duration = 1;            
124         }
125         for(var ix = 1; ix < buidTarget[xUI.Select[0]].length; ix++){
126             if(buidTarget[xUI.Select[0]][ix]==(buidTarget[xUI.Select[0]][ix-1]+1)){
127                 currentSection.duration ++;
128             }else{
129                 buildSections.push({
130                     startFrame:buidTarget[xUI.Select[0]][ix-1]+1,
131                     duration:buidTarget[xUI.Select[0]][ix]-buidTarget[xUI.Select[0]][ix-1]-1,
132                     value:false
133                 });
134                 currentSection = buildSections[buildSections.push({
135                     startFrame:buidTarget[xUI.Select[0]][ix],
136                     duration:1,
137                     value:true
138                 })-1];
139             }
140         }
141         if((currentSection.startFrame + currentSection.duration) < targetTrack.length){
142             buildSections.push({
143                 startFrame:currentSection.startFrame+currentSection.duration,
144                 duration:targetTrack.length-currentSection.startFrame-currentSection.duration,
145                 value:false
146             });        }
147     }
148     if (targetTrack.option.match(/dialog|camera|camerawork|geometry|effect|sfx|composite/)){
149         var backup=[xUI.Select.slice(),xUI.Selection.slice()];
150         for(var sx=0;sx < buildSections.length; sx ++){
151             if (buildSections[sx].value){
152                 xUI.selection();
153                 if(targetTrack.option=='dialog'){
154                     xUI.selectCell([xUI.Select[0],buildSections[sx].startFrame-2]);
155                     var extCount = (buildSections[sx].duration <= 4)? 0 : buildSections[sx].duration-4;
156                     xUI.put('名前,----,セ,リ,フ, ~,'+(new Array(extCount).join(','))+',----')
157                 }else{
158                     xUI.selectCell([xUI.Select[0],buildSections[sx].startFrame]);
159                     var writeContent=["▽"];
160                     for(var cc=0;cc<(buildSections[sx].duration-2);cc++) writeContent.push('|');
161                     writeContent.push("△");
162                     xUI.put(writeContent.join(','));
163                 }
164             }
165         }
166         xUI.selectCell(backup[0]);
167         xUI.selection(add(backup[0],backup[1]));
168     }else{
169         for(var sx=0;sx < buildSections.length; sx ++){
170             if (
171                 (buildSections[sx].startFrame<=xUI.Select[1])&&
172                 ((buildSections[sx].startFrame+buildSections[sx].duration)>xUI.Select[1])
173             ){
174                 xUI.selectCell([xUI.Select[0],buildSections[sx].startFrame]);
175                 xUI.selection([xUI.Select[0],buildSections[sx].startFrame+buildSections[sx].duration-1]);
176                 return;
177             }
178         }
179         
180     }  
181 
182 console.log(buildSections);    
183 }
184     
185       xUI.taskQueue = [];//タスク待ち配列
186 /*
187     配列メソッドのpush/popは使用可能
188     編集も基本的には配列メソッドを使用
189     add(task)
190     タスク優先度の編集が可能なようにする
191     繰り返しタスクの実行間隔はタスク自身で制御可能なようにする
192     タスクにwaitプロパティを置いてインターバル毎に減算を行う?
193     インターバルプロパティにインターバル間隔をミリ秒で設定する  実行間隔0のタスクは毎スキャン毎に実行される?
194     ウェイトプロパティはタスク自身が1タスク終了時に次のタスク実行時限を設定する
195     タスク実行時限に達しないタスクは実行されない
196     タスク実行時限により実行されたタスクのwaitプロパティは、実行コントローラにより0に設定される。
197     このタスクはタスク自身がwaitプロパティを適切に変更しない限りコントローラの次回巡回時に削除される
198     
199     タスクの初期化をコンストラクタ関数一回で行うようにしたい
200 ex:
201     A= new UItask(
202         function(){ヘゲへげ},
203         interval,
204         wait,
205         status
206     )
207      タスク自身を関数として実行すると自身のプロパティをコントロールした後procを実行するように設定する
208      コントローラは、直接はproxを実行しない。
209  */
210       xUI.taskQueue.ctrl=function(){
211          
212       }
213       function UItask(proc,interval,wait,status){
214          this.prox     = proc;
215          this.status   = status;
216          this.interval = interval;
217          this.wait     = wait;
218          this.execute  = function(){
219              this.prox();
220          }
221          this.abort  = function(){
222              
223          }
224          this.stop   =function(){
225              
226          }
227       };
228 /**
229     xUIタスク監視手続
230     タスクウオッチャーは、一定時間でコールされてタスクキューを処理する
231     xUI.taskQueueコレクションにタスクを積む
232     少数のリアルタイム性を要するタスクに関しては、キューの機能をコントローラ自身で監理する
233     キューに格納されるオブジェクトは、基本的には実行可能な関数を引数として持つ
234     それぞれのオブジェクトは以下のステータスを持つ
235     ステータスは実行状態により変化する
236     UItask.status = "waiting";
237 
238     waiting/実行待ち  コントローラはこのタスクを実行してステータスをrunningに変更する
239     running/実行中 既にファイアしているので何も処理しない
240     holding/実行がホールドされている。既にファイアしているので何も処理しない
241     closed/実行が終了している。コントローラは、このタスクを消去する
242     UItask.proc  
243         実際に実行されるプロシジャ
244      タスク自身のオブジェクトメソッドにはしないでコントロール関数を置く
245      タスク実行用のインターバルプロシジャはなるべく小さくする。
246 */
247 xUI.tskWatcher = function(){
248 	var ClockClicks = (new Date()).getTime();
249     var frms = Math.floor((ClockClicks - (xUI.player.startClick+xUI.player.wait)) / (1000 / xUI.XPS.framerate));
250 //play head move
251     if(xUI.player.status  ==  'run'){
252       if(xUI.player.waitCount > 0){
253     	//waiting
254         var count = xUI.player.wait-(ClockClicks-xUI.player.startClick);//スタート後の経過時間をウエイトから減算して残ウエイトを出す
255         if(xUI.player.waitCount) {
256             var waitCountSecond = Math.ceil(xUI.player.waitCount / 1000);//(Math.floor(xUI.player.waitCount%1000/100) < 10)? "":waitCountSecond;//?
257             if(xUI.player.waitCount < 1001){
258             	var countString = (xUI.player.waitCount < 916)?'':xUI.player.countAnimation[11];
259             }else if(xUI.player.waitCount < 3001){	
260             	var countString = ((xUI.player.waitCount%1000) < 750)?'':(xUI.player.countAnimation[12-waitCountSecond]);
261             }else{
262             	var countString = xUI.player.countAnimation[Math.floor((xUI.player.waitCount%1000)/125)+1].replace(/\#/,String(waitCountSecond));	
263             }
264             if(document.getElementById("timerDisplay").innerHTML!=countString)
265             	document.getElementById("timerDisplay").innerHTML=countString;
266             xUI.player.waitCount = count;
267         }else{
268             if(document.getElementById("timerDisplay").innerHTML) document.getElementById("timerDisplay").innerHTML='';
269         }
270       }else{ 
271         var currentOffset = (xUI.selectBackup[1]+frms);//再生開始後の経過フレーム
272         
273         if((! xUI.player.loop)&&(currentOffset >= xUI.XPS.xpsTracks.duration)){
274         	var standbyFrame=(xUI.player.standbyStart)? 0:xUI.XPS.xpsTracks.duration-1;
275             xUI.player.stop();xUI.selectCell([xUI.Select[0],standbyFrame]);//終了フレーム
276         }else{
277             var currentFrame = currentOffset % xUI.XPS.xpsTracks.duration;
278             var currentTrack = (! xUI.player.loop)? xUI.Select[0]:Math.floor(currentOffset/xUI.XPS.xpsTracks.duration);            if((xUI.Select[0] != currentTrack) || (xUI.Select[1] != currentFrame))xUI.selectCell([currentTrack,currentFrame]);
279             if(currentFrame != xUI.player.currentFrame){
280                 xUI.player.currentFrame = currentFrame;
281                 if(xUI.player.getCount){
282                      xUI.player.markFrame([currentTrack,currentFrame]);
283                 }
284             }
285         }
286       }
287 	}
288 /*   タスク列処理  */
289     for(var tid = xUI.taskQueue.length -1 ;tid >= 0; tid --){
290         if(xUI.taskQueue[tid].status == 'waiting'){
291             xUI.taskQueue[tid].status = 'closed';
292             setTimeout(xUI.taskQueue[tid].proc,0);
293         }else if(xUI.taskQueue[tid].status == 'closed') {
294             xUI.taskQueue.splice(tid,1);
295         }
296     }
297 }
298 xUI.taskQueue.push(new UItask());
299 setInterval(xUI.tskWatcher,10);
300 }
301 //  タスク監視スタートアップはこのプロシジャ全体をxUIの再初期化あとに実行する必要あり  2018 08 29
302 // test
303