Version 7 (modified by 12 years ago) (diff) | ,
---|
Bolt implementation notes
Source code
The Bolt source code is part of the BOINC source code distribution. The files related to Bolt are:
Include files:
- bolt.inc: implementation of course document functions.
- bolt_db.inc: Bolt-specific DB abstraction layer.
- db_conn.inc: General DB abstraction layer.
- bolt_ex.inc: Exercise API functions.
- bolt_util.inc: Miscellaneous HTML.
User-visible files:
- bolt.php: List of courses.
- bolt_course_sample.php: Example course document.
- bolt_course.php: Home page for a particular course.
- bolt_sched.php: Scheduler: makes sequencing decisions and adds navigation.
Administrative files:
- bolt_refresh.php: Periodic task to send refresh emails.
- bolt_setup_sample.php: Example script to create a course.
How exercises are implemented
The following information is intended for those who want to add new exercise types.
An exercise is a function that is called with three global variables:
- $bolt_ex_mode
- $bolt_ex_index
- $bolt_ex_score
If $bolt_ex_mode is BOLT_MODE_SHOW, the function should display the exercise, typically generating some "form" input items. $bolt_ex_index is a sequential index (0, 1, ...) indicating the order of this question in a file containing multiple questions; it should be included in form variable names.
If $bolt_ex_mode is BOLT_MODE_SCORE, the function should score the student's response (based on $_GET values) and should store the result (a floating-point number in [0..1]) in $bolt_ex_score.
If $bolt_ex_mode is BOLT_MODE_ANSWER, the function should display an "answer page" that shows the students the correct answers, and whether the student's responses were right or wrong.
Structures
Database tables
Table name | What it represents |
bolt_user | A student, their demographic info, and project-defined attributes |
bolt_course | A course, and the name of its course structure file |
bolt_enrollment | A student taking a course, and the ID of their last view |
bolt_view | A view of an item, created when we show the item, and finalized when the student clicks on something |
bolt_result | The result of a single exercise |
bolt_xset_result | The result of a completed exercise set |
bolt_select_finished | The completion of a select structure |
bolt_refresh | The refresh/repeat of an exercise set, either pending or in progress |
bolt_question | A question asked by a student |
Each table has a corresponding PHP class with names like BoltUser? etc.
PHP "unit" class hierarchy
A "course structure" is a tree of objects of the following types:
- BoltUnit
- BoltItem
- BoltLesson
- BoltExercise
- BoltSet
- BoltRandom
- BoltExerciseSet
- BoltSelect
- BoltRandom
- BoltItem
Each BoltUnit implements an abstract interface (see below).
Course state
A course state represents a student's position in a course. It consists of an array that maps unit names to unit state structures. The contents of a unit state structure depends on the unit. Typically it includes the name of the current child, and its order in the unit's subunits.
A course state is like a call stack, and unit states are like stack frames. One difference: a course state can include records for units that the student is not currently in.
Each BoltView record contains the course state when the view started.
BoltIter
This object is the central data structure of the Bolt scheduler. It includes:
top: the root of the course structure.
state: the course state (from the latest BoltView record).
xset: the xset we're currently in, if any.
item: the current item
frac_done: fraction of course completed so far
Its member functions are:
at(): get current item and fraction done
next(): move to next item
These are both implemented by calling walk() on the root unit.
The interface of BoltUnit
BoltUnit has an abstract function
walk(&$iter, $incr, &$frac_done);
where $iter is a BoltIter object (see below). It is implemented in different ways in the different derived classes. For BoltSet it does the following:
- If there's no unit state record in the course state, set an initial state.
- Otherwise, look up the current child unit, first by name, then by array index.
- Add or replace a unit state record in the $iter->state
- If child is a BoltItem, set $iter->item; otherwise call child->walk().