summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Zorko <robertz@gurucue.com>2015-09-17 10:01:28 +0200
committerRobert Zorko <robertz@gurucue.com>2015-09-17 10:01:28 +0200
commit9fde9cb6cbb628fb882101385009d3b9387dc33d (patch)
tree9063f0769c81ba38cb8330ba24ae47d137fb5968
parentd7d03438ad84376c516a7bd7b2ae28b746637c1c (diff)
improvments to the state machine (states can now be registered) and those improvments are now used for the existing two states (plus some code general code cleanup)
-rw-r--r--index.html2
-rw-r--r--js/codeq/login.js112
-rw-r--r--js/codeq/mainScreen.js126
-rw-r--r--js/codeq/stateMachine.js254
4 files changed, 244 insertions, 250 deletions
diff --git a/index.html b/index.html
index 036641f..ad38b69 100644
--- a/index.html
+++ b/index.html
@@ -135,6 +135,8 @@
<script src="js/prolog.js"></script>
<script src="js/python.js"></script>
<script src="js/codeq/stateMachine.js"></script>
+ <script src="js/codeq/login.js"></script>
+ <script src="js/codeq/mainScreen.js"></script>
<script src="js/codeq/startup.js"></script>
</body>
</html>
diff --git a/js/codeq/login.js b/js/codeq/login.js
new file mode 100644
index 0000000..808d1b3
--- /dev/null
+++ b/js/codeq/login.js
@@ -0,0 +1,112 @@
+/**
+ * Created by robert on 9/17/15.
+ */
+
+(function(){
+ var loginFun = function(){
+ var identifier = $('#problem_group').val().split('/'),
+ problem = $('#problems').val();
+ if (identifier.length < 2) alert('Choose a problem group');
+ else if (!problem) alert('Choose a problem');
+ else {
+ $('#disabled').css('display', '');
+ codeq.comms.login($('#username').val(), $('#password').val())
+ .then(function (data) {
+ $('#disabled').css('display', 'none');
+ if (data.code !== 0) throw new Error('Login failed, code: ' + data.code + ', message: ' + data.message);
+ })
+ .then(function () {
+ return codeq.comms.getProblem(identifier[0], identifier[1], problem);
+ })
+ .then(function (data) {
+ if (data.code !== 0) throw new Error('Failed to obtain problem data, code: ' + data.code + ', message: ' + data.message);
+ $('#disabled').css('display', 'none');
+ switch (identifier[0]) {
+ case 'prolog':
+ // TODO: assignment to window for debug only
+ //$('#screen_login').css('display', 'none');
+ //$('#screen_prolog').css('display', '');
+ codeq.globalStateMachine.transition('prolog');
+ window.phandler = codeq.createPrologHandler(data.data);
+ break;
+ case 'python':
+ // TODO: assignment to window for debug only
+ //$('#screen_login').css('display', 'none');
+ //$('#screen_prolog').css('display', '');
+ codeq.globalStateMachine.transition('prolog');
+ window.phandler = codeq.createPythonHandler(data.data);
+ break;
+ default:
+ alert('Unknown language: ' + identifier[0]);
+ break;
+ }
+ })
+ .fail(function (reason) {
+ $('#disabled').css('display', 'none');
+ alert('Login request failed: ' + reason);
+ })
+ .done();
+ }
+ };
+ codeq.globalStateMachine.register('login',{
+ 'enter': function(){
+ codeq.comms.connect().then(function () {
+ return codeq.comms.send({'action': 'list_problems'});//currently problem list and the actual login are still in the same state
+ }).then(
+ function success(data) {
+ var i, groups, group, problems, problem, first_group,
+ jqGroup = $('#problem_group'),
+ jqProblems = $('#problems'),
+ html = [],
+ mapping = {},
+ onGroupChange = function () {
+ var problems = mapping[jqGroup.val()],
+ html = [],
+ i, p;
+ if (problems) {
+ for (i = 0; i < problems.length; i++) {
+ p = problems[i];
+ html.push('<option value="', p.identifier, '">', p.name, '</option>\n')
+ }
+ }
+ jqProblems.html(html.join(''));
+ };
+
+ if (data && (data.code === 0)) {
+ $('#disabled').css('display', 'none');
+ groups = data.problems;
+ for (i = 0; i < groups.length; i++) {
+ group = groups[i];
+ var identifier = group.identifier.language + '/' + group.identifier.group;
+ var name = group.name.language + ': ' + group.name.group;
+ html.push('<option value="', identifier, '">', name, '</option>\n');
+ mapping[identifier] = group.problems;
+ }
+ jqGroup.html(html.join(''));
+ first_group = html[1];
+ html = null;
+
+ jqGroup.on('click', onGroupChange);
+ jqGroup.val(first_group);
+ onGroupChange();
+
+ $("#submit").on('click', loginFun);
+ }
+ else {
+ $('#disabled').css('cursor', '');
+ alert('Obtaining list of problems failed: code=' + data.code + ', reason=' + data.message);
+ }
+ },
+
+ function failure(reason) {
+ $('#disabled').css('cursor', '');
+ alert('Request to obtain list of problems failed: ' + reason);
+ }
+ ).done();
+ },
+ 'exit' : function(){
+ $("#submit").off('click', loginFun);
+ $("#screen_login").css('display', 'none');
+ }
+ });
+})(); \ No newline at end of file
diff --git a/js/codeq/mainScreen.js b/js/codeq/mainScreen.js
new file mode 100644
index 0000000..8752cbe
--- /dev/null
+++ b/js/codeq/mainScreen.js
@@ -0,0 +1,126 @@
+/**
+ * Created by robert on 9/17/15.
+ */
+
+(function() {
+ var problems,//this will the actual (sub)state machine
+ stateNameTag = 'stateName';
+
+ var divs = {};
+ divs['description'] = $('div.col-lg-3.col-md-6.col-sm-12:has(#description)');//lets actually find the needed divs for later use
+ divs['code'] = $('div.col-lg-3.col-md-6.col-sm-12:has(#code_editor)');
+ divs['console'] = $('div.col-lg-3.col-md-6.col-sm-12:has(#console)');//named 'consoleDiv', because 'console' is already in use
+ divs['info'] = $('div.col-lg-3.col-md-6.col-sm-12:has(#info)');
+
+ divs['description'].data(stateNameTag, 'description');
+ divs['code'].data(stateNameTag, 'code');
+ divs['console'].data(stateNameTag, 'console');
+ divs['info'].data(stateNameTag, 'info');
+
+ var eventName = 'mousedown',//event name of the event which will trigger the transition between these substates
+ mouseDownEventFunction = function () {
+ problems.transition($(this).data(stateNameTag));
+ },
+ removeListenersFromDivs = function () {
+ $.each(divs, function (i, value) {
+ value.off(eventName, mouseDownEventFunction);
+ });
+ },
+ removeBlockClassesFromDivs = function () {
+ $.each(divs, function (i, value) {
+ value.removeClass('block');
+ });
+ },
+ removeChangedClassesFromDivs = function () {
+ $.each(divs, function (i, value) {
+ value.removeClass('block-focus block-less-width block-less-height block-less-everything').addClass('block');//these class names were chosen for the view where the screen is partitioned in 4 quarters (2 by 2)
+ });
+ },
+ setTransitionsBetweenDivs = function (current) {
+ $.each(divs, function (key, value) {
+ if (current !== key) value.on(eventName, mouseDownEventFunction);
+ });
+ },
+ addClassesToDivs = function (divsWithClasses) {
+ $.each(divsWithClasses, function (divName, className) {
+ divs[divName].addClass(className);
+ });
+ },
+ substates = {
+ 'description': {
+ 'enter': function () {
+ removeBlockClassesFromDivs();
+ addClassesToDivs({
+ 'description': 'block-focus',
+ 'code': 'block-less-width',
+ 'console': 'block-less-height',
+ 'info': 'block-less-everything'
+ });
+ setTransitionsBetweenDivs('description');
+ },
+ 'exit': function () {
+ removeChangedClassesFromDivs();
+ removeListenersFromDivs();
+ }
+ },
+ 'code': {
+ 'enter': function () {
+ removeBlockClassesFromDivs();
+ addClassesToDivs({
+ 'description': 'block-less-width',
+ 'code': 'block-focus',
+ 'console': 'block-less-everything',
+ 'info': 'block-less-height'
+ });
+ setTransitionsBetweenDivs('code');
+ },
+ 'exit': function () {
+ removeChangedClassesFromDivs();
+ removeListenersFromDivs();
+ }
+ },
+ 'info': {
+ 'enter': function () {
+ removeBlockClassesFromDivs();
+ addClassesToDivs({
+ 'description': 'block-less-everything',
+ 'code': 'block-less-height',
+ 'console': 'block-less-width',
+ 'info': 'block-focus'
+ });
+ setTransitionsBetweenDivs('info');
+ },
+ 'exit': function () {
+ removeChangedClassesFromDivs();
+ removeListenersFromDivs();
+ }
+ },
+ 'console': {
+ 'enter': function () {
+ removeBlockClassesFromDivs();
+ addClassesToDivs({
+ 'description': 'block-less-height',
+ 'code': 'block-less-everything',
+ 'console': 'block-focus',
+ 'info': 'block-less-width'
+ });
+ setTransitionsBetweenDivs('console');
+ },
+ 'exit': function () {
+ removeChangedClassesFromDivs();
+ removeListenersFromDivs();
+ }
+ }
+ };
+ codeq.globalStateMachine.register('prolog', {
+ 'enter': function () {
+ $('#screen_prolog').css('display', '');
+ problems = codeq.makeStateMachine(substates);
+ problems.transition(divs['description'].data(stateNameTag));
+ },
+ 'exit': function () {
+ $('#screen_prolog').css('display', 'none');
+ problems.destroy();
+ }
+ });
+})(); \ No newline at end of file
diff --git a/js/codeq/stateMachine.js b/js/codeq/stateMachine.js
index 229c8ff..12332c4 100644
--- a/js/codeq/stateMachine.js
+++ b/js/codeq/stateMachine.js
@@ -13,256 +13,10 @@ codeq.makeStateMachine = function(def){
'destroy': function(){
if(currState !== null) currState.exit();
currState = null;
- }
- }
-}
-
-
-
-
-var loginFun = function(){
- var identifier = $('#problem_group').val().split('/'),
- problem = $('#problems').val();
- if (identifier.length < 2) alert('Choose a problem group');
- else if (!problem) alert('Choose a problem');
- else {
- $('#disabled').css('display', '');
- codeq.comms.login($('#username').val(), $('#password').val())
- .then(function (data) {
- $('#disabled').css('display', 'none');
- if (data.code !== 0) throw new Error('Login failed, code: ' + data.code + ', message: ' + data.message);
- })
- .then(function () {
- return codeq.comms.getProblem(identifier[0], identifier[1], problem);
- })
- .then(function (data) {
- if (data.code !== 0) throw new Error('Failed to obtain problem data, code: ' + data.code + ', message: ' + data.message);
- $('#disabled').css('display', 'none');
- switch (identifier[0]) {
- case 'prolog':
- // TODO: assignment to window for debug only
- //$('#screen_login').css('display', 'none');
- //$('#screen_prolog').css('display', '');
- codeq.globalStateMachine.transition('prolog');
- window.phandler = codeq.createPrologHandler(data.data);
- break;
- case 'python':
- // TODO: assignment to window for debug only
- //$('#screen_login').css('display', 'none');
- //$('#screen_prolog').css('display', '');
- codeq.globalStateMachine.transition('prolog');
- window.phandler = codeq.createPythonHandler(data.data);
- break;
- default:
- alert('Unknown language: ' + identifier[0]);
- break;
- }
- })
- .fail(function (reason) {
- $('#disabled').css('display', 'none');
- alert('Login request failed: ' + reason);
- })
- .done();
- }
-};
-
-codeq.globalStateMachine = codeq.makeStateMachine({
- 'login':{
- 'enter': function(){
- codeq.comms.connect().then(function () {
- return codeq.comms.send({'action': 'list_problems'});//currently problem list and the actual login are still in the same state
- }).then(
- function success(data) {
- var i, groups, group, problems, problem, first_group,
- jqGroup = $('#problem_group'),
- jqProblems = $('#problems'),
- html = [],
- mapping = {},
- onGroupChange = function () {
- var problems = mapping[jqGroup.val()],
- html = [],
- i, p;
- if (problems) {
- for (i = 0; i < problems.length; i++) {
- p = problems[i];
- html.push('<option value="', p.identifier, '">', p.name, '</option>\n')
- }
- }
- jqProblems.html(html.join(''));
- };
-
- if (data && (data.code === 0)) {
- $('#disabled').css('display', 'none');
- groups = data.problems;
- for (i = 0; i < groups.length; i++) {
- group = groups[i];
- var identifier = group.identifier.language + '/' + group.identifier.group;
- var name = group.name.language + ': ' + group.name.group;
- html.push('<option value="', identifier, '">', name, '</option>\n');
- mapping[identifier] = group.problems;
- }
- jqGroup.html(html.join(''));
- first_group = html[1];
- html = null;
-
- jqGroup.on('click', onGroupChange);
- jqGroup.val(first_group);
- onGroupChange();
-
- $("#submit").on('click', loginFun);
- }
- else {
- $('#disabled').css('cursor', '');
- alert('Obtaining list of problems failed: code=' + data.code + ', reason=' + data.message);
- }
- },
-
- function failure(reason) {
- $('#disabled').css('cursor', '');
- alert('Request to obtain list of problems failed: ' + reason);
- }
- ).done();
},
- 'exit' : function(){
- $("#submit").off('click', loginFun);
- $("#screen_login").css('display', 'none');
- }
- },
-
- 'prolog':{
- 'enter': function(){
- $('#screen_prolog').css('display', '');
- removeFocusFromElements();
- problems = codeq.makeStateMachine(substates);
- //problems.transition('instructions');
- problems.transition('instructions');
- },
- 'exit': function(){
- $('#screen_prolog').css('display', 'none');
- problems.destroy();
+ 'register': function(name,state){
+ def[name] = state;
}
}
-});
-
-/*
-the following variables are used in the sub-state machine representing the 4 different panels in the codeq app
- */
-var problems,//this will the actual state machine
- description = $('div.col-lg-3.col-md-6.col-sm-12:has(#description)'),//lets actually find the needed divs for later use
- code = $('div.col-lg-3.col-md-6.col-sm-12:has(#code_editor)'),
- consoleDiv = $('div.col-lg-3.col-md-6.col-sm-12:has(#console)'),//named 'consoleDiv', because 'console' is already in use
- info = $('div.col-lg-3.col-md-6.col-sm-12:has(#info)'),
-
- //some functions used inside the enter and exit functions of the state machine
- eventName = 'mousedown',//event name of the event which will trigger the transition between these substates
- mouseDownEventFunctionDescription = function(){
- problems.transition('instructions');
- },
- mouseDownEventFunctionCode = function(){
- problems.transition('code');
- },
- mouseDownEventFunctionConsole = function(){
- problems.transition('console');
- },
- mouseDownEventFunctionInfo = function(){
- problems.transition('info');
- },
- removeListenersFromDivs = function(){
- description.off(eventName,mouseDownEventFunctionDescription);
- code.off(eventName,mouseDownEventFunctionCode);
- consoleDiv.off(eventName,mouseDownEventFunctionConsole);
- info.off(eventName,mouseDownEventFunctionInfo);
- },
- removeBlockClassesFromDivs = function(){
- description.removeClass('block');
- code.removeClass('block');
- consoleDiv.removeClass('block');
- info.removeClass('block');
- },
- removeChangedClassesFromDivs = function(){
- description.removeClass('block-focus block-less-width block-less-height block-less-everything').addClass('block');//these class names were chosen for the view where the screen is partitioned in 4 quarters (2 by 2)
- code.removeClass('block-focus block-less-width block-less-height block-less-everything').addClass('block');
- consoleDiv.removeClass('block-focus block-less-width block-less-height block-less-everything').addClass('block');
- info.removeClass('block-focus block-less-width block-less-height block-less-everything').addClass('block');
- },
- setTransitionsBetweenDivs = function(current){
- if(current !== description)description.on(eventName,mouseDownEventFunctionDescription);
- if(current !== code)code.on( eventName,mouseDownEventFunctionCode);
- if(current !== info)info.on( eventName,mouseDownEventFunctionInfo);
- if(current !== consoleDiv)consoleDiv.on( eventName,mouseDownEventFunctionConsole);
- },
- removeFocusFromElements = function(){
-
- },
-
- //the states of the sub-state machine
- substates = {
- 'instructions':{
- 'enter': function(){
- removeBlockClassesFromDivs();
-
- description.addClass('block-focus');
- code.addClass('block-less-width');
- consoleDiv.addClass('block-less-height');
- info.addClass('block-less-everything');
-
- setTransitionsBetweenDivs(description);
- },
- 'exit': function(){
- removeFocusFromElements();
- removeChangedClassesFromDivs();
- removeListenersFromDivs();
- }
- },
- 'code':{
- 'enter': function(){
- removeBlockClassesFromDivs();
-
- description.addClass('block-less-width');
- code.addClass('block-focus');
- consoleDiv.addClass('block-less-everything');
- info.addClass('block-less-height');
-
- setTransitionsBetweenDivs(code);
- },
- 'exit': function(){
- removeFocusFromElements();
- removeChangedClassesFromDivs();
- removeListenersFromDivs();
- }
- },
- 'info':{
- 'enter': function(){
- removeBlockClassesFromDivs();
-
- description.addClass('block-less-everything');
- code.addClass('block-less-height');
- consoleDiv.addClass('block-less-width');
- info.addClass('block-focus');
-
- setTransitionsBetweenDivs(info);
- },
- 'exit': function(){
- removeFocusFromElements();
- removeChangedClassesFromDivs();
- removeListenersFromDivs();
- }
- },
- 'console':{
- 'enter': function(){
- removeBlockClassesFromDivs();
-
- description.addClass('block-less-height');
- code.addClass('block-less-everything');
- consoleDiv.addClass('block-focus');
- info.addClass('block-less-width');
-
- setTransitionsBetweenDivs(consoleDiv);
- },
- 'exit': function(){
- removeFocusFromElements();
- removeChangedClassesFromDivs();
- removeListenersFromDivs();
- }
- }
- }; \ No newline at end of file
+};
+codeq.globalStateMachine = codeq.makeStateMachine({});