/*
Kapto client component
author: Bruno Fanini (CNR ISPC)
===============================================*/
/**
Kapto
@namespace Kapto
*/
let Kapto = {};
window.Kapto = Kapto;
Kapto.T_INT = 400; //400;
Kapto.CHUNK_SIZE = 30
Kapto._addr = undefined;
Kapto.onFrame = undefined;
Kapto.onSessionID = undefined;
Kapto.onDataChunk = undefined;
Kapto.init = ()=>{
/*
let path = window.location.href.split('?')[0];
var i = path.lastIndexOf('/');
if (i !== -1) path = path.substring( 0, i+1 );
*/
// Defaults to local server, this is not the typical case and you generally tell where is remote hub via setHubServer()
Kapto._addr = window.location.origin+"/";
Kapto._id = undefined;
Kapto._gid = undefined;
Kapto._aname = undefined;
Kapto._bFirstRow = true;
Kapto._bSendingChunk = false;
Kapto._bReqSes = false;
Kapto._resetDataChunk();
Kapto._bRec = false;
Kapto._uf = undefined;
};
/**
is Kapto recording
*/
Kapto.isRecording = ()=>{
return Kapto._bRec;
};
/**
Set Kapto server
@param {String} addr - address (IP or domain)
*/
Kapto.setHubServer = (addr)=>{
Kapto._addr = addr;
console.log("Kapto: " + Kapto._addr);
return Kapto;
};
/**
Set Kapto server
@return {String} addr - Hub address
*/
Kapto.getHubServer = ()=>{
return Kapto._addr;
};
/**
Start recording using ticking
@param {Number} interval - Time interval (milliseconds)
*/
Kapto.start = (interval)=>{
if (Kapto._bRec) return Kapto; // Already recording
if (Kapto._uf) return Kapto;
if (!Kapto._addr) return Kapto;
let dt = interval? interval : Kapto.T_INT;
Kapto._uf = window.setInterval(Kapto._tick, dt);
Kapto._bRec = true;
return Kapto;
};
/**
Set Datachunk size: how large is the packet sent to the Hub
@param {Number} size - Number of frames per packet
*/
Kapto.setDataChunkSize = (size)=>{
if (size < 1) return Kapto;
Kapto.CHUNK_SIZE = size;
return Kapto;
};
Kapto.requestNewSession = (fields)=>{
Kapto._id = undefined;
//let gid = Kapto._gid;
//console.log(gid)
Kapto._bReqSes = true;
fetch(Kapto._addr+"api/session", {
method: "POST",
body: JSON.stringify({
fields: fields,
groupid: Kapto._gid,
actor: Kapto._aname
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then((response) => response.json())
.then((json) => {
console.log(json)
Kapto._id = json.id;
Kapto._gid = json.groupid;
Kapto._bReqSes = false;
if (Kapto.onSessionID) Kapto.onSessionID(Kapto._id);
});
return Kapto;
};
/**
Stop current session
*/
Kapto.stop = ()=>{
if (!Kapto._bRec) return Kapto; // Already stopped
Kapto._sendDataChunk();
Kapto._bRec = false;
Kapto._bFirstRow = true;
window.clearInterval(Kapto._uf);
Kapto._uf = undefined;
console.log("STOP");
return Kapto;
};
/**
Set onFrame routine
@param {Function} of - onFrame routine producing a state (object) each tick
@example
Kapto.setOnFrame(()=>{
return {
x: <my_sample_xvalue>,
y: <my_sample_yvalue>
}
});
*/
Kapto.setOnFrame = (of)=>{
Kapto.onFrame = of;
return Kapto;
};
/**
Set onSessionID routine
@param {Function} of - onSessionID routine to execute on ID assigned
@example
Kapto.setOnSessionID((sesid)=>{
console.log(sesid);
});
*/
Kapto.setOnSessionID = (of)=>{
Kapto.onSessionID = of;
return Kapto;
};
/**
Set onDataChunk routine
@param {Function} of - onDataChunk routine to execute when a datachunk is sent
@example
Kapto.setOnDataChunk((data)=>{
console.log(data);
});
*/
Kapto.setOnDataChunk = (of)=>{
Kapto.onDataChunk = of;
return Kapto;
};
/**
Set group ID
@param {String} gid - group ID (e.g.: "experiment1", "scene3")
*/
Kapto.setGroupID = (gid)=>{
Kapto._gid = gid;
return Kapto;
};
/**
Set actor name
@param {String} actor - friendly name for object we are currently tracking
*/
Kapto.setActorName = (aname)=>{
Kapto._aname = aname;
return Kapto;
};
Kapto._resetDataChunk = ()=>{
Kapto._chunk = [];
Kapto._rcount = 0;
};
Kapto._sendDataChunk = ()=>{
if (Kapto._bSendingChunk) return;
Kapto._bSendingChunk = true;
let sdata = Kapto._chunk.join("\n");
fetch(Kapto._addr+"api/session", {
method: "PUT",
body: JSON.stringify({
id: Kapto._id,
groupid: Kapto._gid,
data: sdata
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then((response) => response.json())
.then((json) => {
Kapto._resetDataChunk();
Kapto._bSendingChunk = false;
//console.log("Chunk sent: "+sdata);
console.log("Datachunk sent");
if (Kapto.onDataChunk) Kapto.onDataChunk(json);
});
};
Kapto._tick = ()=>{
if (!Kapto._bRec) return;
if (!Kapto.onFrame) return;
let S = Kapto.onFrame();
Kapto.frame( S );
};
/**
Record a given frame. Should be used in event-driven scenarios (not using onFrame ticking)
@param {Object} S - State
@example
Kapto.frame({
time: <myclock>,
x: <my_sample_xvalue>,
y: <my_sample_yvalue>
});
*/
Kapto.frame = (S)=>{
if (!S) return Kapto;
if (!Kapto._addr) return Kapto;
if (Kapto._bReqSes) return Kapto;
if (Kapto._bFirstRow){
let fields = [];
for (let a in S) fields.push(a);
Kapto.requestNewSession(fields);
Kapto._bFirstRow = false;
return Kapto;
}
if (!Kapto._id){
//Kapto._bFirstRow = true;
//console.log("ERROR: no valid session ID");
return Kapto;
}
let row = [];
for (let a in S) row.push(S[a]);
let srow = row.join(",");
Kapto._chunk.push(srow);
Kapto._rcount++;
if (Kapto._rcount >= Kapto.CHUNK_SIZE) Kapto._sendDataChunk();
return Kapto;
};
Kapto.init();