mirror of https://github.com/BOINC/boinc.git
- API: fix Win build error
- API: fix Makefile.am - add LGPL license on some files svn path=/trunk/boinc/; revision=14629
This commit is contained in:
parent
9c89b45af2
commit
f682236bd9
|
@ -6,10 +6,12 @@ include $(top_srcdir)/Makefile.incl
|
|||
AM_CFLAGS += @GLUT_CFLAGS@
|
||||
AM_LDFLAGS += @GLUT_LIBS@
|
||||
|
||||
# stuff linked into both main app and graphics app
|
||||
api_files= \
|
||||
boinc_api.C \
|
||||
graphics2_util.C
|
||||
|
||||
# stuff linked into graphics app
|
||||
graphics2_files = \
|
||||
gutil.C \
|
||||
gutil_text.C \
|
||||
|
@ -21,8 +23,8 @@ graphics2_files = \
|
|||
graphics2_unix.C
|
||||
|
||||
if OS_DARWIN
|
||||
api_files += mac_icon.C
|
||||
graphics2_files += macglutfix.m
|
||||
graphics2_files += mac_icon.C
|
||||
graphics2_files += macglutfix.m
|
||||
endif
|
||||
|
||||
EXTRA_DIST = *.h
|
||||
|
|
|
@ -1,3 +1,24 @@
|
|||
// Berkeley Open Infrastructure for Network Computing
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2008 University of California
|
||||
//
|
||||
// This is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation;
|
||||
// either version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This software is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU Lesser General Public License for more details.
|
||||
//
|
||||
// To view the GNU Lesser General Public License visit
|
||||
// http://www.gnu.org/copyleft/lesser.html
|
||||
// or write to the Free Software Foundation, Inc.,
|
||||
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
// platform-independent part of graphics library
|
||||
//
|
||||
#include "util.h"
|
||||
#include "app_ipc.h"
|
||||
#include "shmem.h"
|
||||
|
|
|
@ -1,3 +1,24 @@
|
|||
// Berkeley Open Infrastructure for Network Computing
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2008 University of California
|
||||
//
|
||||
// This is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation;
|
||||
// either version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This software is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU Lesser General Public License for more details.
|
||||
//
|
||||
// To view the GNU Lesser General Public License visit
|
||||
// http://www.gnu.org/copyleft/lesser.html
|
||||
// or write to the Free Software Foundation, Inc.,
|
||||
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
// unix-specific graphics stuff
|
||||
//
|
||||
#include "config.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -1,3 +1,25 @@
|
|||
// Berkeley Open Infrastructure for Network Computing
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2008 University of California
|
||||
//
|
||||
// This is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation;
|
||||
// either version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This software is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU Lesser General Public License for more details.
|
||||
//
|
||||
// To view the GNU Lesser General Public License visit
|
||||
// http://www.gnu.org/copyleft/lesser.html
|
||||
// or write to the Free Software Foundation, Inc.,
|
||||
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
// graphics-related utilities, used both from main applications
|
||||
// (set create shared mem) and by the graphics app
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "boinc_win.h"
|
||||
#elif (!defined(__EMX__))
|
||||
|
|
|
@ -375,18 +375,18 @@ void boinc_graphics_loop(int argc, char** argv) {
|
|||
|
||||
extern int main(int, char**);
|
||||
|
||||
static HINSTANCE hInstance = NULL;
|
||||
static HINSTANCE instance = NULL;
|
||||
|
||||
// call this with the resource names you compiled the icons with
|
||||
// (16x16 and 48x48 pixel)
|
||||
//
|
||||
void boinc_set_windows_icon(const char*icon16,const char*icon48) {
|
||||
void boinc_set_windows_icon(const char* icon16, const char* icon48) {
|
||||
LONG ic;
|
||||
HWND hWnd=FindWindow("BOINC_app",NULL);
|
||||
if (ic=(LONG)LoadIcon(hInstance,icon48)) {
|
||||
if (ic=(LONG)LoadIcon(instance,icon48)) {
|
||||
SetClassLongPtr(hWnd,GCLP_HICON,ic);
|
||||
}
|
||||
if (ic=(LONG)LoadImage(hInstance,icon16, IMAGE_ICON, 16, 16, 0)) {
|
||||
if (ic=(LONG)LoadImage(instance,icon16, IMAGE_ICON, 16, 16, 0)) {
|
||||
SetClassLongPtr(hWnd,GCLP_HICONSM,ic);
|
||||
}
|
||||
}
|
||||
|
@ -396,7 +396,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR Args, int WinMode
|
|||
char* argv[100];
|
||||
int argc;
|
||||
|
||||
hInstance = hInst;
|
||||
instance = hInst;
|
||||
command_line = GetCommandLine();
|
||||
argc = parse_command_line(command_line, argv);
|
||||
main(argc, argv);
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
// or write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
// DEPRECATED - DO NOT USE
|
||||
|
||||
#if defined(_WIN32) && !defined(__STDWX_H__) && !defined(_BOINC_WIN_) && !defined(_AFX_STDAFX_H_)
|
||||
#include "boinc_win.h"
|
||||
#else
|
||||
|
|
|
@ -822,3 +822,16 @@ David Jan 28 2008
|
|||
http_curl.C
|
||||
log_flags.C,h
|
||||
scheduler_op.C
|
||||
|
||||
David Jan 28 2008
|
||||
- API: fix Win build error
|
||||
- API: fix Makefile.am
|
||||
- add LGPL license on some files
|
||||
|
||||
api/
|
||||
Makefile.am
|
||||
graphics_api.C
|
||||
graphics2_win.C
|
||||
graphics2_unix.C
|
||||
graphics2_util.C
|
||||
graphics2.C
|
||||
|
|
|
@ -76,7 +76,7 @@ create table bolt_result (
|
|||
);
|
||||
|
||||
-- represents the result of a completed exercise set,
|
||||
-- where "completed" means the student clicked Next on the final answer page.
|
||||
-- where "completed" means the last exercise was scored.
|
||||
-- In theory this could be reconstructed from the individual exercise results,
|
||||
-- but this table makes it easier for analytics
|
||||
--
|
||||
|
|
|
@ -1,25 +1,11 @@
|
|||
<?php
|
||||
|
||||
// Bolt course document API
|
||||
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', true);
|
||||
ini_set('display_startup_errors', true);
|
||||
|
||||
// stuff needed in Bolt course documents
|
||||
|
||||
// rules about course structures:
|
||||
//
|
||||
// - Each unit has a logical name.
|
||||
// - The members of a set must have distinct logical names
|
||||
// - Different units may have the same logical name;
|
||||
// however, such units must be identical.
|
||||
|
||||
// A state in a course is described by:
|
||||
// - an associative array mapping logical names to state structures.
|
||||
// Typically this includes the logical name of the current child
|
||||
// and info such as a sequence index.
|
||||
// This is kind of like a "call stack",
|
||||
// except that it can contain units not currently active.
|
||||
|
||||
abstract class BoltUnit {
|
||||
public $name; // logical name.
|
||||
public $title;
|
||||
|
@ -36,47 +22,8 @@ abstract class BoltUnit {
|
|||
// frac_done: Fraction done (of this unit and any subunits)
|
||||
}
|
||||
|
||||
// An iterator represents a user's position in a course.
|
||||
// Its state is stored in the database,
|
||||
// and the course may change underneath it.
|
||||
// base class for exercise and lesson
|
||||
//
|
||||
class BoltIter {
|
||||
public $top; // topmost unit
|
||||
public $state;
|
||||
public $xset; // exercise set, if any
|
||||
|
||||
// the following are temps
|
||||
public $item; // current item
|
||||
public $frac_done; // fraction done
|
||||
|
||||
function __construct($top) {
|
||||
$this->top = $top;
|
||||
$this->state = array();
|
||||
}
|
||||
|
||||
function decode_state($encoded_state) {
|
||||
$this->state = json_decode($encoded_state, true);
|
||||
}
|
||||
|
||||
function encode_state() {
|
||||
return json_encode($this->state);
|
||||
}
|
||||
|
||||
// get current item and fraction done
|
||||
//
|
||||
function at() {
|
||||
$this->xset = null;
|
||||
$this->top->walk($this, false, $this->frac_done);
|
||||
}
|
||||
|
||||
// move to the next item, and return it in $this->item
|
||||
// (null if course finished)
|
||||
//
|
||||
function next() {
|
||||
$this->top->walk($this, true, $this->frac_done);
|
||||
}
|
||||
}
|
||||
|
||||
class BoltItem extends BoltUnit {
|
||||
public $filename;
|
||||
public $query_string;
|
||||
|
@ -113,6 +60,106 @@ class BoltExercise extends BoltItem {
|
|||
}
|
||||
}
|
||||
|
||||
// Base class for control structures (i.e. all units that are not items).
|
||||
// These have the following properties:
|
||||
// - a set of units
|
||||
// - an ordering of this set, defined in the derived class
|
||||
// (i.e., random, student-specific, or identity)
|
||||
// - an index (state_rec::index) for where we are in this list
|
||||
// - an index (state_rec::nshown) for how many units completed so far
|
||||
// - a number "ntoshow" for how many to show
|
||||
//
|
||||
class BoltSet extends BoltUnit {
|
||||
public $units;
|
||||
function __construct($name, $units, $ntoshow) {
|
||||
$this->name = $name;
|
||||
$this->is_item = false;
|
||||
$this->units = $units;
|
||||
$this->ntoshow = $ntoshow;
|
||||
$this->ordered = false;
|
||||
}
|
||||
function walk(&$iter, $incr, &$frac_done) {
|
||||
$n = count($this->units);
|
||||
if (array_key_exists($this->name, $iter->state)) {
|
||||
$state_rec = $iter->state[$this->name];
|
||||
$child_name = $state_rec['child_name'];
|
||||
$nshown = $state_rec['nshown'];
|
||||
if (!$this->ordered) {
|
||||
$this->order($state_rec);
|
||||
$this->ordered = true;
|
||||
}
|
||||
|
||||
// look up unit by name
|
||||
//
|
||||
$child = null;
|
||||
for ($i=0; $i<$n; $i++) {
|
||||
$c = $this->units[$i];
|
||||
if ($c->name == $child_name) {
|
||||
$child = $c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if not there, look up by index
|
||||
//
|
||||
if (!$child) {
|
||||
$i = $state_rec['index'];
|
||||
if ($i >= $n) {
|
||||
// and if index is too big, use last unit
|
||||
//
|
||||
$i = $n-1;
|
||||
}
|
||||
$child = $this->units[$i];
|
||||
}
|
||||
|
||||
// at this point, $child is the current unit, and $i is its index
|
||||
//
|
||||
if ($incr) {
|
||||
if ($child->is_item) {
|
||||
$my_inc = true;
|
||||
} else {
|
||||
$my_inc = $child->walk($iter, $incr, $frac_done);
|
||||
}
|
||||
if ($my_inc) {
|
||||
$nshown++;
|
||||
if ($nshown == $this->ntoshow) {
|
||||
$frac_done = 1;
|
||||
$state_rec['nshown'] = 0;
|
||||
$state_rec['child_name'] = null;
|
||||
$iter->state[$this->name] = $state_rec;
|
||||
return true;
|
||||
} else {
|
||||
$i = ($i+1)%$n;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// here if no state record; initialize
|
||||
//
|
||||
$i = 0;
|
||||
$nshown = 0;
|
||||
$state_rec = null;
|
||||
$this->order($state_rec);
|
||||
}
|
||||
|
||||
// at this point, $i is index of current child
|
||||
//
|
||||
$child = $this->units[$i];
|
||||
$frac_done = $nshown/$n;
|
||||
$state_rec['index'] = $i;
|
||||
$state_rec['nshown'] = $nshown;
|
||||
$state_rec['child_name'] = $child->name;
|
||||
$iter->state[$this->name] = $state_rec;
|
||||
if ($child->is_item) {
|
||||
$iter->item = $child;
|
||||
} else {
|
||||
$child->walk($iter, false, $f);
|
||||
$frac_done += $f*(1/$n);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function name($n) {
|
||||
return array('name', $n);
|
||||
}
|
||||
|
@ -185,19 +232,6 @@ function exercise() {
|
|||
return new BoltExercise($name, $title, $file);
|
||||
}
|
||||
|
||||
function enum_course($course) {
|
||||
$iter = new BoltIter($course);
|
||||
while (1) {
|
||||
$x = $iter->at();
|
||||
if (!$x) break;
|
||||
echo "at: $x->url\n";
|
||||
$x = $iter->next();
|
||||
if (!$x) break;
|
||||
echo "next: $x->filename\n";
|
||||
}
|
||||
echo "course over\n";
|
||||
}
|
||||
|
||||
require_once('../inc/bolt_seq.inc');
|
||||
require_once('../inc/bolt_rnd.inc');
|
||||
require_once('../inc/bolt_xset.inc');
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
// Bolt exercise API
|
||||
|
||||
$bolt_ex_mode = 0;
|
||||
$bolt_ex_index = 0;
|
||||
$bolt_ex_state = 0;
|
||||
|
|
|
@ -1,99 +1,20 @@
|
|||
<?php
|
||||
|
||||
// state for random unit is:
|
||||
// seed The RNG seed used to shuffle
|
||||
// i index of current child
|
||||
// number_shown number of units shown so far (not necessarily the
|
||||
// same as i on 2nd and later pass through this unit)
|
||||
// child_name name of current child
|
||||
class BoltRandom extends BoltUnit {
|
||||
class BoltRandom extends BoltSet {
|
||||
public $units;
|
||||
function __construct($name, $units, $number) {
|
||||
$this->name = $name;
|
||||
$this->units = $units;
|
||||
$this->number = $number;
|
||||
$this->is_item = false;
|
||||
$this->shuffled = false;
|
||||
parent::__construct($name, $units, $number);
|
||||
}
|
||||
|
||||
function walk(&$iter, $incr, &$frac_done) {
|
||||
$n = count($this->units);
|
||||
if (array_key_exists($this->name, $iter->state)) {
|
||||
$state_rec = $iter->state[$this->name];
|
||||
$child_name = $state_rec['child_name'];
|
||||
$number_shown = $state_rec['number_shown'];
|
||||
if (!$this->shuffled) {
|
||||
srand($state_rec['seed']);
|
||||
shuffle($this->units);
|
||||
$this->shuffled = true;
|
||||
}
|
||||
|
||||
// look up unit by name
|
||||
//
|
||||
$child = null;
|
||||
for ($i=0; $i<$n; $i++) {
|
||||
$c = $this->units[$i];
|
||||
if ($c->name == $child_name) {
|
||||
$child = $c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if not there, look up by index
|
||||
//
|
||||
if (!$child) {
|
||||
$i = $state_rec['i'];
|
||||
if ($i >= $n) {
|
||||
// and if index is too big, use last unit
|
||||
//
|
||||
$i = $n-1;
|
||||
}
|
||||
$child = $this->units[$i];
|
||||
}
|
||||
|
||||
// at this point, $child is the current unit, and $i is its index
|
||||
//
|
||||
if ($incr) {
|
||||
$my_inc = false;
|
||||
if ($child->is_item) {
|
||||
$my_inc = true;
|
||||
} else {
|
||||
$my_inc = $child->walk($iter, $incr, $frac_done);
|
||||
}
|
||||
if ($my_inc) {
|
||||
$i = ($i+1)%$n;
|
||||
$number_shown++;
|
||||
if ($number_shown >= $this->number) {
|
||||
$frac_done = 1;
|
||||
$state_rec['i'] = $i;
|
||||
$state_rec['number_shown'] = 0;
|
||||
$state_rec['child_name'] = null;
|
||||
$iter->state[$this->name] = $state_rec;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
function order(&$state_rec) {
|
||||
if ($state_rec) {
|
||||
$seed = $state_rec['seed'];
|
||||
} else {
|
||||
$i = 0;
|
||||
$number_shown = 0;
|
||||
$state_rec = null;
|
||||
$seed = ((double)microtime()*1000000);
|
||||
srand($seed);
|
||||
shuffle($this->units);
|
||||
$state_rec['seed'] = $seed;
|
||||
}
|
||||
$child = $this->units[$i];
|
||||
$frac_done = $number_shown/$this->number;
|
||||
$state_rec['i'] = $i;
|
||||
$state_rec['number_shown'] = $number_shown;
|
||||
$state_rec['child_name'] = $child->name;
|
||||
$iter->state[$this->name] = $state_rec;
|
||||
if ($child->is_item) {
|
||||
$iter->item = $child;
|
||||
} else {
|
||||
$child->walk($iter, false, $f);
|
||||
$frac_done += $f*(1/$number);
|
||||
}
|
||||
srand($seed);
|
||||
shuffle($this->units);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
// An iterator represents a user's position in a course.
|
||||
// Its state is stored in the database,
|
||||
// and the course may change underneath it.
|
||||
//
|
||||
// A state in a course is described by:
|
||||
// - an associative array mapping logical names to state structures.
|
||||
// Typically this includes the logical name of the current child
|
||||
// and info such as a sequence index.
|
||||
// This is kind of like a "call stack",
|
||||
// except that it can contain units not currently active.
|
||||
|
||||
//
|
||||
class BoltIter {
|
||||
public $top; // topmost unit
|
||||
public $state;
|
||||
public $xset; // exercise set, if any
|
||||
|
||||
// the following are temps
|
||||
public $item; // current item
|
||||
public $frac_done; // fraction done
|
||||
|
||||
function __construct($top) {
|
||||
$this->top = $top;
|
||||
$this->state = array();
|
||||
}
|
||||
|
||||
function decode_state($encoded_state) {
|
||||
$this->state = json_decode($encoded_state, true);
|
||||
}
|
||||
|
||||
function encode_state() {
|
||||
return json_encode($this->state);
|
||||
}
|
||||
|
||||
// get current item and fraction done
|
||||
//
|
||||
function at() {
|
||||
$this->xset = null;
|
||||
$this->top->walk($this, false, $this->frac_done);
|
||||
}
|
||||
|
||||
// move to the next item, and return it in $this->item
|
||||
// (null if course finished)
|
||||
//
|
||||
function next() {
|
||||
$this->top->walk($this, true, $this->frac_done);
|
||||
}
|
||||
}
|
||||
|
||||
function enum_course($course) {
|
||||
$iter = new BoltIter($course);
|
||||
while (1) {
|
||||
$x = $iter->at();
|
||||
if (!$x) break;
|
||||
echo "at: $x->url\n";
|
||||
$x = $iter->next();
|
||||
if (!$x) break;
|
||||
echo "next: $x->filename\n";
|
||||
}
|
||||
echo "course over\n";
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,77 +1,11 @@
|
|||
<?php
|
||||
|
||||
class BoltSequence extends BoltUnit {
|
||||
public $units;
|
||||
class BoltSequence extends BoltSet {
|
||||
function __construct($name, $units) {
|
||||
$this->name = $name;
|
||||
$this->units = $units;
|
||||
$this->is_item = false;
|
||||
parent::__construct($name, $units, count($units));
|
||||
}
|
||||
|
||||
function walk(&$iter, $incr, &$frac_done) {
|
||||
$n = count($this->units);
|
||||
if (array_key_exists($this->name, $iter->state)) {
|
||||
$state_rec = $iter->state[$this->name];
|
||||
$child_name = $state_rec['child_name'];
|
||||
|
||||
// look up unit by name
|
||||
//
|
||||
$child = null;
|
||||
for ($i=0; $i<$n; $i++) {
|
||||
$c = $this->units[$i];
|
||||
if ($c->name == $child_name) {
|
||||
$child = $c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if not there, look up by index
|
||||
//
|
||||
if (!$child) {
|
||||
$i = $state_rec['i'];
|
||||
if ($i >= $n) {
|
||||
// and if index is too big, use last unit
|
||||
//
|
||||
$i = $n-1;
|
||||
}
|
||||
$child = $this->units[$i];
|
||||
}
|
||||
|
||||
// at this point, $child is the current unit, and $i is its index
|
||||
//
|
||||
if ($incr) {
|
||||
$my_inc = false;
|
||||
if ($child->is_item) {
|
||||
$my_inc = true;
|
||||
} else {
|
||||
$my_inc = $child->walk($iter, $incr, $frac_done);
|
||||
}
|
||||
if ($my_inc) {
|
||||
$i++;
|
||||
if ($i == $n) {
|
||||
$frac_done = 1;
|
||||
$state_rec['i'] = 0;
|
||||
$state_rec['child_name'] = null;
|
||||
$iter->state[$this->name] = $state_rec;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$i = 0;
|
||||
}
|
||||
$child = $this->units[$i];
|
||||
$frac_done = $i/$n;
|
||||
$state_rec = null;
|
||||
$state_rec['i'] = $i;
|
||||
$state_rec['child_name'] = $child->name;
|
||||
$iter->state[$this->name] = $state_rec;
|
||||
if ($child->is_item) {
|
||||
$iter->item = $child;
|
||||
} else {
|
||||
$child->walk($iter, false, $f);
|
||||
$frac_done += $f*(1/$n);
|
||||
}
|
||||
function order() {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,128 +1,48 @@
|
|||
<?php
|
||||
|
||||
class BoltExerciseSet extends BoltUnit {
|
||||
public $units;
|
||||
class BoltExerciseSet extends BoltRandom {
|
||||
public $repeats;
|
||||
public $state_rec;
|
||||
function __construct($name, $units, $number, $repeats) {
|
||||
$this->name = $name;
|
||||
$this->units = $units;
|
||||
$this->number = $number;
|
||||
parent::__construct($name, $units, $number);
|
||||
$this->repeats = $repeats;
|
||||
$this->is_item = false;
|
||||
$this->shuffled = false;
|
||||
}
|
||||
|
||||
// the scheduler calls this when an exercise in this set
|
||||
// has just been graded.
|
||||
// called when an exercise in this set has just been graded.
|
||||
// - record the score in our state structure
|
||||
// - return a structure saying what navigation info to show:
|
||||
// - review
|
||||
// - repeat now
|
||||
// - next
|
||||
//
|
||||
function xset_callback($iter, $score, &$is_last, &$nav_info) {
|
||||
function xset_callback(&$iter, $score, $view_id, &$is_last, &$nav_info) {
|
||||
echo "XSET_CALLBACK: $score";
|
||||
$nav_info = null;
|
||||
$state_rec = $iter->state[$this->name];
|
||||
$number_shown = $state_rec['number_shown'];
|
||||
$state_rec['scores'][$number_shown] = $score;
|
||||
$is_last = ($number_shown == $this->number);
|
||||
if ($is_last) {
|
||||
} else {
|
||||
}
|
||||
}
|
||||
$nshown = $state_rec['nshown'];
|
||||
$state_rec['scores'][$nshown] = $score;
|
||||
$iter->state[$this->name] = $state_rec;
|
||||
$is_last = ($nshown == $this->ntoshow);
|
||||
if (!$is_last) return;
|
||||
|
||||
// this exercise set is now "completed".
|
||||
// - create exercise_set_result record
|
||||
// - optionally create or update bolt_refresh record
|
||||
//
|
||||
$total_score = 0;
|
||||
for ($i=0; $i<$nshown; $i++) {
|
||||
$total_score += $state_rec['score'][$i];
|
||||
}
|
||||
$avg_score = $total_score/$nshown;
|
||||
|
||||
// The user clicked "Next" on last answer page,
|
||||
// so this exercise set is now "completed".
|
||||
// - create exercise_set_result record
|
||||
// - optionally create or update bolt_refresh record
|
||||
//
|
||||
function completed($score, $view_id) {
|
||||
$now = time();
|
||||
$id = BoincXsetResult::insert("(create_time, user_id, course_id, name, score, view_id) values ($now, $user->id, $course->id, '$this->name', $score, $view_id)");
|
||||
$id = BoincXsetResult::insert("(create_time, user_id, course_id, name, score, view_id) values ($now, $user->id, $course->id, '$this->name', $avg_score, $view_id)");
|
||||
$due_time = $now + 100000;
|
||||
BoincRefresh::replace("create_time=$now, user_id=$user->id, course_id=$course->id, name='$this->name', set_result_id=$id, due_time=$due_time");
|
||||
}
|
||||
|
||||
function walk(&$iter, $incr, &$frac_done) {
|
||||
$iter->xset = $this;
|
||||
$n = count($this->units);
|
||||
if (array_key_exists($this->name, $iter->state)) {
|
||||
$state_rec = $iter->state[$this->name];
|
||||
$this->state_rec = $state_rec;
|
||||
$child_name = $state_rec['child_name'];
|
||||
$number_shown = $state_rec['number_shown'];
|
||||
if (!$this->shuffled) {
|
||||
srand($state_rec['seed']);
|
||||
shuffle($this->units);
|
||||
$this->shuffled = true;
|
||||
}
|
||||
|
||||
// look up unit by name
|
||||
//
|
||||
$child = null;
|
||||
for ($i=0; $i<$n; $i++) {
|
||||
$c = $this->units[$i];
|
||||
if ($c->name == $child_name) {
|
||||
$child = $c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if not there, look up by index
|
||||
//
|
||||
if (!$child) {
|
||||
$i = $state_rec['i'];
|
||||
if ($i >= $n) {
|
||||
// and if index is too big, use last unit
|
||||
//
|
||||
$i = $n-1;
|
||||
}
|
||||
$child = $this->units[$i];
|
||||
}
|
||||
|
||||
// at this point, $child is the current unit, and $i is its index
|
||||
//
|
||||
if ($incr) {
|
||||
$my_inc = false;
|
||||
if ($child->is_item) {
|
||||
$my_inc = true;
|
||||
} else {
|
||||
$my_inc = $child->walk($iter, $incr, $frac_done);
|
||||
}
|
||||
if ($my_inc) {
|
||||
$i = ($i+1)%$n;
|
||||
$number_shown++;
|
||||
if ($number_shown >= $this->number) {
|
||||
$frac_done = 1;
|
||||
$state_rec['i'] = $i;
|
||||
$state_rec['number_shown'] = 0;
|
||||
$state_rec['child_name'] = null;
|
||||
$iter->state[$this->name] = $state_rec;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$i = 0;
|
||||
$number_shown = 0;
|
||||
$state_rec = null;
|
||||
$seed = ((double)microtime()*1000000);
|
||||
srand($seed);
|
||||
shuffle($this->units);
|
||||
$state_rec['seed'] = $seed;
|
||||
}
|
||||
$child = $this->units[$i];
|
||||
$frac_done = $number_shown/$this->number;
|
||||
$state_rec['i'] = $i;
|
||||
$state_rec['number_shown'] = $number_shown;
|
||||
$state_rec['child_name'] = $child->name;
|
||||
$iter->state[$this->name] = $state_rec;
|
||||
if ($child->is_item) {
|
||||
$iter->item = $child;
|
||||
} else {
|
||||
$child->walk($iter, false, $f);
|
||||
$frac_done += $f*(1/$number);
|
||||
}
|
||||
return parent::walk($iter, $incr, $frac_done);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
// action: see commands below
|
||||
|
||||
require_once("../inc/bolt.inc");
|
||||
require_once("../inc/bolt_sched.inc");
|
||||
require_once("../inc/bolt_db.inc");
|
||||
require_once("../inc/bolt_ex.inc");
|
||||
require_once("../inc/bolt_util.inc");
|
||||
|
@ -261,11 +262,11 @@ case 'next': // "next" button in lesson or exercise answer page
|
|||
break;
|
||||
case 'answer': // submit answer in exercise
|
||||
$view = finalize_view($user, $view_id, BOLT_ACTION_SUBMIT);
|
||||
if ($user->bolt->debug) {
|
||||
echo "<pre>State: $view->state</pre>\n";
|
||||
}
|
||||
$iter = new BoltIter($course_doc);
|
||||
$iter->decode_state($view->state);
|
||||
if ($user->bolt->debug) {
|
||||
echo "<pre>Initial state:"; print_r($iter->state); echo "</pre>\n";
|
||||
}
|
||||
$iter->at();
|
||||
|
||||
if ($user->bolt->debug) {
|
||||
|
@ -303,6 +304,12 @@ case 'answer': // submit answer in exercise
|
|||
);
|
||||
$view->update("result_id=$result_id");
|
||||
|
||||
// If this is part of an exercise set, call its callback function
|
||||
//
|
||||
if ($iter->xset) {
|
||||
$iter->xset->xset_callback($iter, $bolt_ex_score, $view->id, $is_last, $nav_info);
|
||||
}
|
||||
|
||||
// show the answer page
|
||||
|
||||
srand($view_id);
|
||||
|
|
Loading…
Reference in New Issue