Safety checks
[ajatus.git] / js / ajatus.events.js
blob5b5b1494297a7bf27ba9c31c54356ecb7403f531
1 /*
2  * This file is part of
3  *
4  * Ajatus - Distributed CRM
5  * @requires jQuery v1.2.1
6  * 
7  * Copyright (c) 2007 Jerry Jalava <jerry.jalava@gmail.com>
8  * Copyright (c) 2007 Nemein Oy <http://nemein.com>
9  * Website: http://ajatus.info
10  * Licensed under the GPL license
11  * http://www.gnu.org/licenses/gpl.html
12  * 
13  */
15 (function($){
16     $.ajatus = $.ajatus || {};
17     $.ajatus.locker = $.ajatus.locker || {};
18     $.ajatus.events = $.ajatus.events || {};
20     $.ajatus.events.locks = {
21         list: []
22     };
23     $.extend($.ajatus.events.locks, {
24         add: function(lock)
25         {
26             var new_count = $.ajatus.events.locks.list.push(lock);            
27             return new_count-1;
28         },
29         remove: function(index)
30         {            
31             $.ajatus.events.locks.list = $.grep( $.ajatus.events.locks.list, function(n,i){
32                 return i == index;
33             });
34         },
35         update: function(index, lock)
36         {
37             $.ajatus.events.locks.list[index] = lock;
38         }
39     });
40     
41     $.ajatus.events.lock = function(options)
42     {
43         this._manual = true;
44         this._watcher = null;
45         this.options = $.extend({
46             msg: '<h1><img src="'+$.ajatus.preferences.client.theme_url+'images/loading-small.gif" /> ' + $.ajatus.i10n.get('Loading Ajatus') + '...</h1>',
47             dialog: false,
48             watch: false,
49             on_release: false,
50             disable_application: true
51         }, options);
53         this._id = $.ajatus.events.locks.add(this);
54         
55         if (   !this.options.dialog
56             && this.options.disable_application)
57         {
58             $.blockUI(this.options.msg);
59         }
60         
61         if (this.options.watch)
62         {
63             var watcher_opts = {
64                 after: true,
65                 auto_start: false
66             };
67             $.each(this.options.watch, function(i,n){
68                 if (i != 'after')
69                 {
70                     watcher_opts[i] = n;                    
71                 }
72             });
73             this._watcher = new $.ajatus.events.watcher(watcher_opts);
74             
75             var self = this;
76             this._watcher.element.bind('on_stop', function(watcher_id){
77                 self.release();
78             });
79             
80             this._watcher.start();
81         }
83         $.ajatus.events.locks.update(this);        
84         return this;
85     };
86     $.extend($.ajatus.events.lock.prototype, {
87         release: function() {
88             if (   !this.options.dialog
89                 && this.options.disable_application)
90             {
91                 $.unblockUI();
92             }
93             
94             if (   this.options.on_release
95                 && typeof(this.options.on_release) == 'function')
96             {
97                 this.options.on_release(this);
98             }
99         },
100         update: function(lock_cnt) {
101             if (lock_cnt == 0) {
102                 this._release_lock();
103             }
104         }
105     });
106     
107     $.ajatus.events.watchers = {
108         list: []
109     };
110     $.extend($.ajatus.events.watchers, {
111         add: function(watcher) {
112             var new_count = $.ajatus.events.watchers.list.push(watcher);
113             return new_count-1;
114         },
115         remove: function(index) {
116             if (typeof $.ajatus.events.watchers.list[index] != 'undefined') {
117                 delete($.ajatus.events.watchers.list[index]);
118             }
119             // $.ajatus.events.watchers.list = $.grep( $.ajatus.events.watchers.list, function(n,i){
120             //     return i == index;
121             // });
122         }
123     });
124     
125     $.ajatus.events.watcher = function(options) {
126         this.options = $.extend({
127             validate: null,
128             after: false,
129             interval: 1000,
130             safety_runs: 3,
131             auto_start: true,
132             max_runs: 100,
133             timed: 0
134         }, options);
136         if (   typeof(this.options.validate) != 'function'
137             && this.options.timed <= 0)
138         {
139             return false;
140         }
141         
142         if (this.options.timed > 0) {
143             this.options.max_runs = false;
144         }
145         
146         this.elapsed = 0;
147         this._timeout_id = -1;
148         this._done_safety_runs = 0;
149         this._done_runs = 0;
150         
151         this._id = $.ajatus.events.watchers.add(this);
152         this.element = $('<div id="ajatus_events_watcher_'+this._id+'" />').appendTo($('body'));
154         if (this.options.auto_start) {
155             this.start();
156         }
157         
158         return this;
159     };
160     $.extend($.ajatus.events.watcher.prototype, {
161         start: function() {
162             if (this.options.interval < 200) {
163                 this.options.interval = 200;  // Safari needs at least 200 ms
164             }
165             // console.log("Watcher "+this._id+" started!");
166             this._timeout_id = setTimeout("if (typeof $.ajatus.events.watchers.list["+this._id+"] != 'undefined') {$.ajatus.events.watchers.list["+this._id+"]._check();}", this.options.interval);
167         },
168         _check: function() {
169             // console.log("Watcher "+this._id+" is checking status");
170             if (typeof $.ajatus.events.watchers.list[this._id] == 'undefined') {
171                 this._cleanup();
172             };
173             
174             this._done_runs++;
175             
176             if (this.options.timed > 0) {
177                 if (   this.elapsed >= this.options.timed
178                     || (   this.options.max_runs
179                         && this._done_runs >= (this.options.max_runs-this.options.safety_runs)))
180                 {
181                     this._stop();
182                 } else {
183                     this._done_safety_runs = 0;
184                     this.elapsed += this.options.interval;
185                     this._timeout_id = setTimeout("if (typeof $.ajatus.events.watchers.list["+this._id+"] != 'undefined') {$.ajatus.events.watchers.list["+this._id+"]._check();}", this.options.interval);
186                 }
187             } else {
188                 if (   this.options.validate()
189                     || (   this.options.max_runs
190                         && this._done_runs >= (this.options.max_runs-this.options.safety_runs)))
191                 {
192                     // console.log("Watcher "+this._id+" validated!");
194                     if (this._done_safety_runs < this.options.safety_runs) {
195                         this._done_safety_runs++;
196                         //console.log("Watcher "+this._id+" doing safety run: "+this._done_safety_runs+" of "+this.options.safety_runs);
197                         this._timeout_id = setTimeout("if (typeof $.ajatus.events.watchers.list["+this._id+"] != 'undefined') {$.ajatus.events.watchers.list["+this._id+"]._check();}", this.options.interval);
198                     } else {
199                         //console.log("Watcher "+this._id+" has done all safety runs!");                    
200                         this._stop();
201                     }
202                 } else {
203                     this._done_safety_runs = 0;
204                     this._timeout_id = setTimeout("if (typeof $.ajatus.events.watchers.list["+this._id+"] != 'undefined') {$.ajatus.events.watchers.list["+this._id+"]._check();}", this.options.interval);
205                 }                
206             }
207             var tick_data = {
208                 done_runs: this._done_runs,
209                 elapsed: this.elapsed,
210             };
211             if (this.options.timed > 0) {
212                 tick_data['elapsed'] = this.elapsed;
213                 tick_data['timed'] = this.options.timed;
214                 tick_data['left_ms'] = this.options.timed - this.elapsed;
215                 tick_data['left_prc'] = (this.elapsed/this.options.timed)*100;
216             }
217             this.element.trigger('on_tick',[this._id, tick_data]);
218         },
219         _stop: function() {
220             // console.log("Watcher "+this._id+" ended!");
221             this._cleanup();
222             
223             this.element.trigger('on_stop',[this._id]);
224         },
225         _cleanup: function() {
226             // console.log("CleanUp "+this._id);
227             clearTimeout(this._timeout_id);
228             //$.ajatus.events.watchers.remove(this._id);
229         }
230     });
231     
232     $.ajatus.events.lock_pool = {
233         count: 0,
234         increase: function() {
235             $.ajatus.events.lock_pool.count = $.ajatus.events.named_lock_pool.increase('global');
236             // console.log('lock_pool increase to '+$.ajatus.events.lock_pool.count);
237         },
238         decrease: function() {
239             $.ajatus.events.lock_pool.count = $.ajatus.events.named_lock_pool.decrease('global');            
240             // console.log('lock_pool decrease to '+$.ajatus.events.lock_pool.count);
241         },
242         clear: function() {
243             $.ajatus.events.named_lock_pool.clear('global');
244             $.ajatus.events.lock_pool.count = 0;
245         }
246     };
247     
248     $.ajatus.events.named_lock_pool = {
249         counts: {},
250         count: function(name) {
251             if ($.ajatus.events.named_lock_pool.counts[name] == undefined) {
252                 return 0;
253             } else {
254                 return $.ajatus.events.named_lock_pool.counts[name];
255             }            
256         },
257         increase: function(name) {
258             if ($.ajatus.events.named_lock_pool.counts[name] == undefined) {
259                 $.ajatus.events.named_lock_pool.counts[name] = 0;
260             }
261             $.ajatus.events.named_lock_pool.counts[name]++;
263             //console.log('named_lock_pool increase '+name+' to '+$.ajatus.events.named_lock_pool.counts[name]);
264             return $.ajatus.events.named_lock_pool.counts[name];
265         },
266         decrease: function(name) {
267             if ($.ajatus.events.named_lock_pool.counts[name] == undefined) {
268                 $.ajatus.events.named_lock_pool.counts[name] = 0;
269             } else {
270                 $.ajatus.events.named_lock_pool.counts[name] = $.ajatus.events.named_lock_pool.counts[name]-1;
271             }
272             // console.log('named_lock_pool decrease '+name+' to '+$.ajatus.events.named_lock_pool.counts[name]);
273             return $.ajatus.events.named_lock_pool.counts[name];
274         },
275         clear: function(name) {
276             $.ajatus.events.named_lock_pool.counts[name] = 0;
277         }
278     };
280 })(jQuery);