Overriding Wordlist component function to use Multiple Datasets.

Overview

One of the tasks for GSoC 2019 included adding multiple datasets to smallNumbers activity. The aim of the activity is to teach students to count the number of object on the falling item. But the activity is not an independent activity, but it is the sub-activity of the parent activity gletters. In gletter the overall working is the same, apart from the fact that this time their are no falling objects but alphabets, and the student has to identify the falling alphabet and press the corresponding button on the keyboard. So to manage different types of falling items the activity uses a separate core component i.e. Wordlist. Now since the task was to implement the multiple datasets for smallnumbers activity without affecting the functionalitiy of its parent activity gletters, I had to make some changes in wordlist component.

Wordlist initially reading data

The Wordlist component uses a loadFromFile function which is provided the path to the file location which contains the dataset. The files provided are json files and the function uses a parser to parse the contents of the file.

function loadFromFile(fname) {
    function loadFromFile(fname) {
        filename = fname;
        var from;
        maxLevel = 0
        wordList = parser.parseFromUrl(filename, validateWordlist);
        if (wordList == null) {
            error("Wordlist: Invalid wordlist file " + fname);
            if (useDefault) {
                // fallback to default file:
                wordList = parser.parseFromUrl(defaultFilename, validateWordlist);
                if (wordList == null) {
                    error("Wordlist: Invalid wordlist file " + defaultFilename);
                    return;
                }
                from = "default-file " + defaultFilename;
            }
            else {
                error("Wordlist: do not use default list, no list loaded");
                return;
            }
        } else {
            from = "file " + fname;
        }
        // at this point we have valid levels
        maxLevel = wordList.levels.length;
        console.log("Wordlist: loaded " + maxLevel + " levels from " + from);
        return wordList;

but in case of multiple datasets we use qml files to store data and hence the same function could not be used with multiple datasets.

Creating a new function to initialise wordlist

In Multiple dataset architecture we are provided with the data part of the Data.qml file in the main qml file of our activity like

property var levels: activity.datasetLoader.item.data

This data is already in JSON format, which is exactly what is needed by the Wordlist. So I created a function loadFromJSON in Wordlist component to take this data as input and initialise the Wordlist according to it.

 function loadFromJSON(levels) {
    wordList = {levels: levels};
    maxLevel = wordList.levels.length;
    return wordList;
}

Lastly I added a condition in gletters.js file to use the respective function when there is some value in items.levels variable(when the activity uses multiple datasets).

if(!items.levels)
    items.wordlist.loadFromFile(GCompris.ApplicationInfo.getLocaleFilePath(
        items.ourActivity.dataSetUrl + "default-"+locale+".json"));
else
    items.wordlist.loadFromJSON(items.levels);

This way I was able to use multiple datasets in smallnumbers activity without affecting the functionality of parent activity gletters.

Comments

Popular posts from this blog

Generating generic questions for calendar activity.

Multiple Datasets: Overview