changeset 2674:b9efbbe0d829

#191: Now added to <page> nodes the “position” attribute
author Nicholas Jillings <nicholas.jillings@mail.bcu.ac.uk>
date Thu, 13 Apr 2017 11:36:24 +0100
parents 0b1c48849b4f
children 2b14c1d1f893 04cc7a27ae64 2dfc19a33bbc
files js/core.js js/specification.js xml/test-schema.xsd
diffstat 3 files changed, 57 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/js/core.js	Wed Mar 29 15:56:22 2017 +0100
+++ b/js/core.js	Thu Apr 13 11:36:24 2017 +0100
@@ -1175,6 +1175,21 @@
 
 function stateMachine() {
     // Object prototype for tracking and managing the test state
+
+    function pickSubPool(pool, numElements) {
+        // Assumes each element of pool has function "alwaysInclude"
+
+        // First extract those excluded from picking process
+        var picked = [];
+        pool.forEach(function (e) {
+            if (e.alwaysInclude) {
+                picked.push(e);
+            }
+        });
+
+        return picked.concat(randomSubArray(pool, numElements - excluded.length));
+    }
+
     this.stateMap = [];
     this.preTestSurvey = null;
     this.postTestSurvey = null;
@@ -1186,63 +1201,55 @@
 
         // Get the data from Specification
         var pagePool = [];
-        var pageInclude = [];
         for (var page of specification.pages) {
-            if (page.alwaysInclude) {
-                pageInclude.push(page);
-            } else {
-                pagePool.push(page);
+            if (page.position !== null || page.alwaysInclude) {
+                page.alwaysInclude = true;
+            }
+            pagePool.push(page)
+        }
+        if (specification.numPages > 0) {
+            specification.randomiseOrder = true;
+            pagePool = pickSubPool(pagePool, specification.numPages);
+        }
+
+        // Now get the order of pages
+        var fixed = []
+        for (var page of pagePool) {
+            if (page.position !== null) {
+                fixed.push(page);
+                var i = pagePool.indexOf(page);
+                pagePool.splice(i, 1);
             }
         }
 
-        // Find how many are left to get
-        var numPages = specification.poolSize;
-        if (numPages > pagePool.length) {
-            console.log("WARNING - You have specified more pages in <setup poolSize> than you have created!!");
-            numPages = specification.pages.length;
-        }
-        if (specification.poolSize == 0) {
-            numPages = specification.pages.length;
-        }
-        numPages -= pageInclude.length;
-
-        if (numPages > 0) {
-            // Go find the rest of the pages from the pool
-            var subarr = null;
-            if (specification.randomiseOrder) {
-                // Append a random sub-array
-                subarr = randomSubArray(pagePool, numPages);
-            } else {
-                // Append the matching number
-                subarr = pagePool.slice(0, numPages);
-            }
-            pageInclude = pageInclude.concat(subarr);
+        if (specification.randomiseOrder) {
+            pagePool = randomiseOrder(pagePool);
         }
 
-        // We now have our selected pages in pageInclude array
-        if (specification.randomiseOrder) {
-            pageInclude = randomiseOrder(pageInclude);
+        // Place in the correct order
+        for (var page of fixed) {
+            pagePool.splice(page.position, 0, page)
         }
-        for (var i = 0; i < pageInclude.length; i++) {
-            pageInclude[i].presentedId = i;
-            this.stateMap.push(pageInclude[i]);
-            // For each selected page, we must get the sub pool
-            if (pageInclude[i].poolSize != 0 && pageInclude[i].poolSize != pageInclude[i].audioElements.length) {
-                var elemInclude = [];
-                var elemPool = [];
-                for (var elem of pageInclude[i].audioElements) {
-                    if (elem.alwaysInclude || elem.type != "normal") {
-                        elemInclude.push(elem);
-                    } else {
-                        elemPool.push(elem);
-                    }
+
+        // Now process the pages
+        pagePool.forEach(function (page, i) {
+            page.presentedId = i;
+            this.stateMap.push(page);
+            var elements = page.audioElements
+            if (page.poolSize > 0 || page.randomiseOrder) {
+                page.randomiseOrder = true;
+                if (page.poolSize == 0) {
+                    page.poolSize = page.randomiseOrder;
                 }
-                var numElems = pageInclude[i].poolSize - elemInclude.length;
-                pageInclude[i].audioElements = elemInclude.concat(randomSubArray(elemPool, numElems));
+                elements = pickSubPool(elements, page.poolSize);
             }
-            storage.createTestPageStore(pageInclude[i]);
-            audioEngineContext.loadPageData(pageInclude[i]);
-        }
+            if (page.randomiseOrder) {
+                elements = randomiseOrder(elements);
+            }
+            page.audioElements = elements;
+            storage.createTestPageStore(page);
+            audioEngineContext.loadPageData(page);
+        }, this)
 
         if (specification.preTest != null) {
             this.preTestSurvey = specification.preTest;
--- a/js/specification.js	Wed Mar 29 15:56:22 2017 +0100
+++ b/js/specification.js	Thu Apr 13 11:36:24 2017 +0100
@@ -521,6 +521,7 @@
         this.interfaces = [];
         this.playOne = null;
         this.restrictMovement = null;
+        this.position = null;
         this.commentBoxPrefix = "Comment on track";
         this.audioElements = [];
         this.commentQuestions = [];
--- a/xml/test-schema.xsd	Wed Mar 29 15:56:22 2017 +0100
+++ b/xml/test-schema.xsd	Thu Apr 13 11:36:24 2017 +0100
@@ -100,6 +100,7 @@
                 <xs:attribute name="labelStart" type="xs:string" use="optional" default="" />
                 <xs:attribute ref="poolSize" />
                 <xs:attribute ref="alwaysInclude" />
+                <xs:attribute name="position" use="optional" type="xs:nonNegativeInteger" />
                 <xs:attribute ref="preSilence" />
                 <xs:attribute ref="postSilence" />
                 <xs:attribute ref="playOne" />