Commit d42faaf0 authored by László Domoszlai's avatar László Domoszlai
Browse files

- fix bug of "StdGeneric.PAIR not found" something

- support of strict tuples
- restore RunOnClient functionality

git-svn-id: https://svn.cs.ru.nl/repos/iTask-system/trunk@2823 63da3aa8-80fd-4f01-9db8-e6ea747a3da2
parent 41522c52
This diff was suppressed by a .gitattributes entry.
......@@ -16,6 +16,8 @@ Ext.define('itwc.container.Tasklet', {
controllerFunc: null,
instanceNo: null,
updater: null,
// indicates whether the defualt TUI is already included or not
tuiIncluded: false,
// for detecting whether the result is changed
......@@ -61,9 +63,13 @@ Ext.define('itwc.container.Tasklet', {
}
eval("var tmp = eval(" + this.st + ");");
this.st = tmp;
itwc.global.controller.tasklets[this.taskId] = this;
this.st = Sapl.feval(tmp);
itwc.global.controller.tasklets[this.taskId] = this;
if(!_iworld){
_iworld = Sapl.fapp(__iTasks_Framework_Client_RunOnClient_createClientIWorld, [this.instanceNo]);
}
if(this.resultFunc != null){
eval("var tmp = eval(" + this.resultFunc + ");");
this.resultFunc = tmp;
......@@ -71,12 +77,26 @@ Ext.define('itwc.container.Tasklet', {
}
if(this.controllerFunc != null){
var start = new Date().getTime();
eval("var tmp = eval(" + this.controllerFunc + ");");
this.controllerFunc = tmp;
itwc.global.controller.taskletControllers[this.instanceNo] = this;
var ret = Sapl.fapp(this.controllerFunc, [this.taskId, this.st, 0, __Data_Maybe_Nothing, __Data_Maybe_Nothing, _iworld]);
this.st = Sapl.feval(ret[3]);
_iworld = Sapl.feval(ret[4]);
var ui = Sapl.toJS(Sapl.feval(ret[2]));
this.tui = JSON.parse(ui);
if (this.tui.xtype=="itwc_viewport") this.tui = this.tui.items[0];
var end = new Date().getTime();
console.log(end-start);
}
DB.saveTasklet(this);
//DB.saveTasklet(this);
this.callParent(arguments);
},
......@@ -87,6 +107,23 @@ Ext.define('itwc.container.Tasklet', {
this.tuiIncluded = true;
this.tui = this.lookupComponent(this.tui);
this.add(this.tui);
var me = this;
me.updater = window.setInterval(function(){
var ret = Sapl.fapp(me.controllerFunc, [me.taskId, me.st, 0, __Data_Maybe_Nothing, __Data_Maybe_Nothing, _iworld]);
me.st = Sapl.feval(ret[3]);
_iworld = Sapl.feval(ret[4]);
var tui = Sapl.toJS(Sapl.feval(ret[2]));
tui = JSON.parse(tui);
if (tui.xtype=="itwc_viewport") tui = tui.items[0];
applytui(me.tui, tui);
},500);
}
this.callParent(arguments);
......@@ -129,6 +166,10 @@ Ext.define('itwc.container.Tasklet', {
onDestroy: function() {
if(this.updater){
window.clearInterval(this.updater);
}
this.fireTaskletEvent("destroy");
this.callParent(arguments);
},
......
// TO BE SURE
function ___predefined__Tuple3(__a1, __a2, __a3) {
return [0, '_predefined._Tuple3', __a1, __a2, __a3];
function ___Tuple3(_1, _2, _3) {
return [0, '_Tuple3', _1, _2, _3];
};
function ___predefined__Tuple2(__a1, __a2) {
return [0, '_predefined._Tuple2', __a1, __a2];
function ___Tuple2(_1, _2) {
return [0, '_Tuple2', _1, _2];
};
var __Data_Maybe_Nothing = [0,"Data.Maybe.Nothing"];
......@@ -233,7 +233,7 @@ function _array_replace$eval(arr, idx, e){
function _array_replace(arr, idx, e){
var o = arr[idx];
arr[idx] = e;
return ___predefined__Tuple2(o, arr);
return ___Tuple2(o, arr);
}
function _array_select_lazy(arr, idx){
......@@ -245,7 +245,7 @@ function _array_select(arr, idx){
}
function _array_uselect(arr, idx){
return ___predefined__Tuple2(_Sapl.feval(arr)[Sapl.feval(idx)],arr);
return ___Tuple2(_Sapl.feval(arr)[Sapl.feval(idx)],arr);
}
function _array_size(arr){
......@@ -253,7 +253,7 @@ function _array_size(arr){
}
function _array_usize(arr){
return ___predefined__Tuple2(_Sapl.feval(arr).length,arr);
return ___Tuple2(_Sapl.feval(arr).length,arr);
}
// ----------------------------------------------------------------
......@@ -264,7 +264,7 @@ function _string_size(str){
}
function _string_usize(str){
return ___predefined__Tuple2(Sapl.feval(str).length,str);
return ___Tuple2(Sapl.feval(str).length,str);
}
function _string_select(str, pos){
......@@ -272,7 +272,7 @@ function _string_select(str, pos){
}
function _string_uselect(str, pos){
return ___predefined__Tuple2(Sapl.feval(str).charAt(Sapl.feval(pos)),str);
return ___Tuple2(Sapl.feval(str).charAt(Sapl.feval(pos)),str);
}
function _string_create1$eval(len){
......@@ -300,7 +300,7 @@ function _string_replace$eval(str, idx, c){
}
function _string_replace(str, idx, c){
return ___predefined__Tuple2(str.charAt(idx), str.replaceAt(idx,c));
return ___Tuple2(str.charAt(idx), str.replaceAt(idx,c));
}
function _string_slice(str, ind1, ind2){
......@@ -360,15 +360,11 @@ function _tupsels4v3(a){
// Other stuff
function _error(str){
throw "ERROR: "+str;
throw "ERROR: "+Sapl.feval(str);
}
function _abort(str){
throw "ABORT: "+str;
}
function __dynamic_handler(){
return "DYNVAL";
throw "ABORT: "+Sapl.feval(str);
}
function __sapldebug(str, f){
......@@ -379,39 +375,3 @@ function __sapldebug(str, f){
}
}
// ----------------------------------------------------------------
// Function overrides
function __sapldebug_sapldebug(a,b){
console.log("DEBUG: "+Sapl.toString(a));
return b;
}
function __iTasks_Framework_ClientSupport_ClientOverride_onClient(){
return true;
}
function __iTasks_Framework_ClientSupport_ClientOverride_cast_to_TaskValue(___vTC_0, ___vTC_1, __a_2) {
return Sapl.feval(__a_2);
};
function __iTasks_Framework_ClientSupport_ClientOverride_cast(___vTC_0, ___vTC_1, __a_2) {
return Sapl.feval(__a_2);
};
function __dynamic_string_copy_to_string(a){
return Sapl.dynamicToString(Sapl.feval(a));
}
function __dynamic_string_copy_from_string(a){
eval("var tmp="+Sapl.feval(a)+";");
return ___predefined__Tuple2(tmp, a); // TODO: second?
}
function __Text_Encodings_Base64_base64Encode(a){
return window.btoa(Sapl.feval(a));
}
function __Text_Encodings_Base64_base64Decode(a){
return window.atob(Sapl.feval(a));
}
......@@ -33,11 +33,15 @@ function ___SystemDynamic__DynamicTemp(__a1, __a2) {
};
function ___SystemDynamic__initial_unification_environment(n_type_pattern_vars, n_type_vars){
return; // undefined will do it
return undefined; // undefined will do it
};
// Don't do anything
function ___SystemDynamic__normalise(subst, t) { return t; };
function ___SystemDynamic__bind_global_type_pattern_var(t1, t2, subst) { return subst; };
function ___SystemDynamic__unify(subst, t1, t2){
return ___predefined__Tuple2(unify(t1, Sapl.heval(t2), true), subst);
return ___Tuple2(unify(t1, Sapl.heval(t2), true), subst);
};
// Very simple unification algorithm
......@@ -102,7 +106,7 @@ function getType(val){
}else if(isArray(val)){
if(val[0] == 0 && val[1].startsWith("_predefined._Tuple")){
if(val[0] == 0 && val[1].startsWith("_Tuple")){
return applyTypes(val.slice(2,val.length), tupleType(val.length-2));
}
......
......@@ -25,13 +25,13 @@ function __iTasks_API_Core_Client_Interface_jsDocument() {
//jsThis :: !*JSWorld -> (!JSVal a,!*JSWorld)
function __iTasks_API_Core_Client_Interface_jsThis(world) {
world = Sapl.feval(world);
return ___predefined__Tuple2(___wrapJS(this), world);
return ___Tuple2(___wrapJS(this), world);
}
//jsEmptyObject :: !*JSWorld -> (!JSVal a, !*JSWorld)
function __iTasks_API_Core_Client_Interface_jsEmptyObject(world) {
world = Sapl.feval(world);
return ___predefined__Tuple2(___wrapJS({}), world);
return ___Tuple2(___wrapJS({}), world);
}
//jsNewObject :: !String ![JSPtr a] !*JSWorld -> *(!JSPtr b, !*JSWorld)
......@@ -42,7 +42,7 @@ function __iTasks_API_Core_Client_Interface_jsNewObject(cons_name, args, world){
args = [null].concat(args);
var factoryFunction = Object.prototype.constructor.bind.apply(eval(cons_name), args);
return ___predefined__Tuple2(___wrapJS(new factoryFunction()), world);
return ___Tuple2(___wrapJS(new factoryFunction()), world);
}
//jsGetObjectAttr :: !String !(JSVal a) !*JSWorld -> *(!JSVal b, !*JSWorld)
......@@ -70,7 +70,7 @@ function __iTasks_API_Core_Client_Interface_jsGetObjectAttr(attr,obj,world) {
if(typeof value == 'undefined') {
console.warn("jsGetObjectAttr: accessed undefined attribute: "+attr);
}
return ___predefined__Tuple2(___wrapJS(value), world);
return ___Tuple2(___wrapJS(value), world);
}
//jsGetObjectEl :: !Int !(JSVal o) !*JSWorld -> *(!JSVal b, !*JSWorld)
......@@ -80,7 +80,7 @@ function __iTasks_API_Core_Client_Interface_jsGetObjectEl(index,obj,world) {
index = Sapl.feval(index);
obj = ___unwrapJS(Sapl.feval(obj));
return ___predefined__Tuple2(___wrapJS(obj[index]), world);
return ___Tuple2(___wrapJS(obj[index]), world);
}
//jsSetObjectAttr :: !String !(JSVal v) !(JSVal o) !*JSWorld -> *JSWorld
......@@ -143,7 +143,7 @@ function __iTasks_API_Core_Client_Interface_jsApply(fun,scope,args,world) {
console.warn("jsApply: Evaluating function with undefined scope");
}
return ___predefined__Tuple2(___wrapJS(fun.apply(scope,args)), world);
return ___Tuple2(___wrapJS(fun.apply(scope,args)), world);
}
//jsTypeof :: !(JSVal a) -> !String
......@@ -160,7 +160,7 @@ function __iTasks_API_Core_Client_Interface_jsAbort(obj) {
// newJSArray :: !*JSWorld -> *(!JSVal [a], !*JSWorld)
function __iTasks_API_Core_Client_Interface_newJSArray(world){
world = Sapl.feval(world);
return ___predefined__Tuple2(___wrapJS([]), world);
return ___Tuple2(___wrapJS([]), world);
}
// toJSVal :: !a -> JSVal b
......
var _iworld;
/**
* eventType can be "edit" or "commit" or "init". It is necessary because eventValue can be null
* even in the case of "edit" event.
*/
function controllerWrapper(controllerFunc,taskId,eventType,eventName,eventValue){
function controllerWrapper(controllerFunc,taskId,eventNo,eventType,eventName,eventValue){
console.time('controllerWrapper timer: eval');
var tasklet = itwc.global.controller.tasklets[taskId];
var taskletId = taskId.split("-")[0] + "-0";
var tasklet = itwc.global.controller.tasklets[taskletId];
var state = tasklet.st;
var tmp = [controllerFunc,[]];
tmp[1].push(taskId);
tmp[1].push(state);
tmp[1].push(eventNo);
if(eventType == "edit" || eventType == "commit"){
tmp[1].push([1, 'Just', eventName])
......@@ -26,11 +30,14 @@ function controllerWrapper(controllerFunc,taskId,eventType,eventName,eventValue)
tmp[1].push([0, 'Nothing']);
}
tmp[1].push(_iworld);
// result is a tuple of mbTUI and state
var ys = Sapl.feval(tmp);
state = Sapl.heval(ys[3]);
itwc.global.controller.tasklets[taskId].st = state; // save it
_iworld = Sapl.feval(ys[4]);
itwc.global.controller.tasklets[taskletId].st = state; // save it
// toJS to make the result hyperstrict
var newres = Sapl.toJS(Sapl.feval([tasklet.resultFunc,[state]]));
......@@ -39,28 +46,32 @@ function controllerWrapper(controllerFunc,taskId,eventType,eventName,eventValue)
// If mbTUI is Nothing, the task is finished. TODO: is it still true?
if(mbTUI[0] == 0){
DB.removeTasklet(taskId);
//DB.removeTasklet(taskId);
itwc.global.controller.sendEditEvent(tasklet.taskId, "finalize", newres);
}else{
var tuistr = Sapl.feval(mbTUI[2]);
console.timeEnd('controllerWrapper timer: eval');
/*
console.time('controllerWrapper timer: serialization');
DB.updateTasklet(tasklet,
null,
tuistr);
console.timeEnd('controllerWrapper timer: serialization');
*/
console.time('controllerWrapper timer: apply TUI');
eval("var tui = " + tuistr + ";");
//eval("var tui = " + tuistr + ";");
var tui = JSON.parse(tuistr);
if (tui.xtype=="itwc_viewport") tui = tui.items[0];
applytui(tasklet.tui, tui);
console.timeEnd('controllerWrapper timer: apply TUI');
// Send result to the client if it is changed only
if(!geq(itwc.global.controller.tasklets[taskId].lastResult, newres)){
itwc.global.controller.tasklets[taskId].lastResult = newres;
itwc.global.controller.sendEditEvent(tasklet.taskId, "result", newres);
if(!geq(tasklet.lastResult, newres)){
tasklet.lastResult = newres;
itwc.global.controller.sendEditEvent(taskletId, "result", newres);
}
}
......@@ -174,3 +185,102 @@ function __iTasks_Framework_Client_Tasklet_handleJSEvent(expr,taskId,event){
itwc.global.controller.sendEditEvent(tasklet.taskId, "result", newres);
}
}
// ----------------------------------------------------------------
// JSStore
var _store = {}
function __iTasks_Framework_Client_JSStore_jsStoreValue(namespace,key,value,iworld){
var iworld = Sapl.feval(iworld);
var namespace = Sapl.feval(namespace);
var key = Sapl.feval(key);
var value = Sapl.feval(value);
if(!_store[namespace]) _store[namespace]={};
_store[namespace][key] = value;
return iworld;
}
function __iTasks_Framework_Client_JSStore_jsLoadValue(namespace,key,iworld){
var iworld = Sapl.feval(iworld);
var namespace = Sapl.feval(namespace);
var key = Sapl.feval(key);
var ret = __Data_Maybe_Nothing;
if(_store[namespace]){
var val = _store[namespace][key];
if(val){
ret = __Data_Maybe_Just(val);
}
}
return ___Tuple2(ret, iworld);
}
// ----------------------------------------------------------------
// Time
function ___time(world){
world = Sapl.feval(world);
var d = new Date();
var t = __System_Time_Timestamp(d.getTime());
return ___Tuple2(t, world);
}
function ___localTime(world){
world = Sapl.feval(world);
var d = new Date();
var start = new Date(d.getFullYear(), 0, 0);
var diff = d - start;
var oneDay = 1000 * 60 * 60 * 24;
var dayofyear = Math.floor(diff / oneDay);
var tm = __System_Time__Tm(
d.getSeconds(),
d.getMinutes(),
d.getHours(),
d.getDate(), // day of the month
d.getMonth(),
d.getYear(),
d.getDay(), // day of the week
dayofyear,
d.dst());
return ___Tuple2(tm, world);
}
// ----------------------------------------------------------------
// General function overrides
function __sapldebug_sapldebug(a,b){
console.log("DEBUG: "+Sapl.toString(a));
return b;
}
function __dynamic_string_copy_to_string(a){
return Sapl.dynamicToString(Sapl.feval(a));
}
function __dynamic_string_copy_from_string(a){
eval("var tmp="+Sapl.feval(a)+";");
return ___Tuple2(tmp, a); // TODO: second?
}
function __iTasks_Framework_Client_RunOnClient_newWorld(){
return "WORLD";
}
function __iTasks_Framework_Client_Override_cast_to_TaskValue(___vTC_0, ___vTC_1, __a_2) {
return Sapl.feval(__a_2);
};
function __iTasks_Framework_Client_Override_cast(___vTC_0, ___vTC_1, __a_2) {
return Sapl.feval(__a_2);
};
......@@ -142,7 +142,7 @@ Sapl = new function () {
}
this.toTuple = function (arr){
var prefix = [0, '_predefined._Tuple'+arr.length];
var prefix = [0, '_Tuple'+arr.length];
// Concat doesn't work here if "arr" is "argument" because "argument" is not an array
for(var i=0; i<arr.length; i++) prefix.push(arr[i]);
return prefix;
......@@ -223,7 +223,7 @@ Sapl = new function () {
var arraycons = this.isCons(consname);
if (!arraycons && !consname.startsWith("_predefined._Tuple")) {
if (!arraycons && !consname.startsWith("_Tuple")) {
res.push(this.print_consname(consname));
}
......
......@@ -70,6 +70,16 @@ String.prototype.rpad = function(padString, length) {
return str;
}
Date.prototype.stdTimezoneOffset = function() {
var jan = new Date(this.getFullYear(), 0, 1);
var jul = new Date(this.getFullYear(), 6, 1);
return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());
}
Date.prototype.dst = function() {
return this.getTimezoneOffset() < this.stdTimezoneOffset();
}
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
if (!Object.keys) {
Object.keys = (function () {
......
module Movin
import iTasks, iTasks.API.Core.Client.Tasklet
//-------------------------------------------------------------------------
:: Position :== Int
movinTasklet :: Tasklet Position Void
movinTasklet =
{ genUI = generateGUI
, resultFunc = const (Value Void False)
, tweakUI = id
}
generateGUI :: !TaskId (Maybe Position) !*IWorld -> *(!TaskletGUI Position, !Position, !*IWorld)
generateGUI taskId Nothing iworld = generateGUI taskId (Just 0) iworld
generateGUI _ (Just x) iworld
# gui = { width = ExactSize 800
, height = ExactSize 600
, html = RawText ("<div id=\"object\" style=\""+++style+++"\">Airplane</div>")
, eventHandlers = [ ComponentEvent "tasklet" "init" onInit
, ComponentEvent "tasklet" "update" onInit]
}
= (TaskletHTML gui, x, iworld)
where
style = "position:absolute; left:"+++toString x+++"px;top:8em;width:5em;line-height:3em;background:#99ccff;border:1px solid #003366;white-space:nowrap;padding:0.5em;"
onInit _ _ x world
# world = setDomAttr "object" "style.left" (toJSVal (toString x+++"px")) world
= (x, world)
:: Cmd = SetPosX Position
derive class iTask Cmd
tasklet :: Task Void
tasklet
= withShared (SetPosX 0) (\pos ->
mkTaskWithShared movinTasklet pos updateFun
-||
forever (wait 10 >>- update (moveForward 40) pos ))
where
updateFun :: Cmd Position -> Position
updateFun (SetPosX x) st = x
moveForward :: Position Cmd -> Cmd
moveForward px (SetPosX x) = SetPosX (x+px)
//UTIL
(>>-) infixl 1 :: !(Task a) (Task b) -> Task b | iTask a & iTask b
(>>-) taska taskb = step taska (const Nothing) [OnValue (ifStable (const taskb))]
//Wait for (at least) n seconds
wait :: Int -> Task Void
wait n = get currentTime >>= \start -> watch currentTime >>* [OnValue (\(Value now _) -> if (now > addSeconds n start) (Just (return Void)) Nothing)]
where
//ONLY CORRECT FOR n < 60
addSeconds n t = t + {Time|hour=0,min=0,sec=n}
Start :: *World -> *World
Start world = startEngine tasklet world
This diff is collapsed.
module SharedTasklet
import iTasks, iTasks.API.Core.Client.Tasklet
//-------------------------------------------------------------------------
:: Position :== Int
movinTasklet :: Tasklet Position Position
movinTasklet =