Changed the last embedPC() parameter from sStateFile to sParms, although for backward compatibility, if sParms is not a JSON object definition (ie, beginning with a brace), it continues to be treated as a state filename.
This change allows us to pass any number of additional properties to embedPC(), which in turn can override properties contained in the XML file; the only property overrides currently supported are 'state' (which overrides any 'state' property set in the XML's <computer> element) and 'automount' (which overrides any 'automount' property set in the XML's <fdc> element). The goal is to make it easier to reuse XML machine definitions, by allowing commonly altered component attributes to be overridden.
This commit is contained in:
parent
5d2da60d67
commit
12b760f912
28 changed files with 2187 additions and 2059 deletions
|
|
@ -82,7 +82,7 @@ if (NODE) {
|
|||
* @param {Object} [parmsMachine]
|
||||
* @param {boolean} [fSuspended]
|
||||
*
|
||||
* The Computer component has no required (parmsComputer) properties, but does
|
||||
* The Computer component has no required (parmsComputer) properties, but it does
|
||||
* support the following:
|
||||
*
|
||||
* autoPower: true to automatically power the computer (default), false to wait;
|
||||
|
|
@ -102,6 +102,16 @@ if (NODE) {
|
|||
*
|
||||
* state: the path to JSON-encoded state file (see details regarding 'state' below)
|
||||
*
|
||||
* The parmsMachine object, if provided, may contain any of:
|
||||
*
|
||||
* url: the location of the machine XML file
|
||||
*
|
||||
* autoMount: if set, this should override any 'autoMount' property in the FDC's
|
||||
* parmsFDC object.
|
||||
*
|
||||
* state: if set, this should override any 'state' property in the Computer's
|
||||
* parmsComputer object.
|
||||
*
|
||||
* If a predefined state is supplied AND it's successfully loaded, then resume behavior
|
||||
* defaults to '1' (ie, resume enabled without prompting).
|
||||
*
|
||||
|
|
@ -141,7 +151,9 @@ function Computer(parmsComputer, parmsMachine, fSuspended) {
|
|||
this.sStateData = null;
|
||||
this.fStateData = false; // remembers if sStateData was loaded
|
||||
this.fServerState = false;
|
||||
this.url = parmsMachine? parmsMachine['url'] : null;
|
||||
|
||||
this.parmsMachine = parmsMachine;
|
||||
this.url = this.getMachineParm('url') || "";
|
||||
|
||||
/*
|
||||
* Generate a random number x (where 0 <= x < 1), add 0.1 so that it's guaranteed to be
|
||||
|
|
@ -230,7 +242,7 @@ function Computer(parmsComputer, parmsMachine, fSuspended) {
|
|||
* localStorage (in other words, it prevents fAllowResume from being true, and forcing resume off).
|
||||
*/
|
||||
var fAllowResume;
|
||||
var sState = Component.parmsURL && Component.parmsURL['state'] || (fAllowResume = true) && parmsComputer['state'];
|
||||
var sState = Component.parmsURL && Component.parmsURL['state'] || this.getMachineParm('state') || (fAllowResume = true) && parmsComputer['state'];
|
||||
|
||||
if (sState) {
|
||||
sStatePath = this.sStatePath = sState;
|
||||
|
|
@ -318,6 +330,17 @@ Computer.prototype.getMachineID = function()
|
|||
return this.sMachineID;
|
||||
};
|
||||
|
||||
/**
|
||||
* getMachineParm(sParm)
|
||||
*
|
||||
* @param {string} sParm
|
||||
* @return {string|undefined}
|
||||
*/
|
||||
Computer.prototype.getMachineParm = function(sParm)
|
||||
{
|
||||
return this.parmsMachine && this.parmsMachine[sParm];
|
||||
};
|
||||
|
||||
/**
|
||||
* getUserID()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -142,22 +142,11 @@ function FDC(parmsFDC) {
|
|||
this['dmaWrite'] = this.dmaWrite;
|
||||
this['dmaFormat'] = this.dmaFormat;
|
||||
|
||||
this.configMount = null;
|
||||
if (parmsFDC['autoMount']) {
|
||||
this.configMount = parmsFDC['autoMount'];
|
||||
if (typeof this.configMount == "string") {
|
||||
try {
|
||||
/*
|
||||
* The most likely source of any exception will be right here, where we're parsing
|
||||
* the JSON-encoded diskette data.
|
||||
*/
|
||||
this.configMount = eval("(" + parmsFDC['autoMount'] + ")");
|
||||
} catch (e) {
|
||||
Component.error("FDC auto-mount error: " + e.message + " (" + parmsFDC['autoMount'] + ")");
|
||||
this.configMount = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* We record any 'autoMount' object now, but we no longer parse it until initBus(), because the Computer's
|
||||
* getMachineParm() service may have an override for us.
|
||||
*/
|
||||
this.configMount = parmsFDC['autoMount'] || null;
|
||||
|
||||
/*
|
||||
* The following array keeps track of every disk image we've ever mounted. Each entry in the
|
||||
|
|
@ -533,6 +522,23 @@ FDC.prototype.initBus = function(cmp, bus, cpu, dbg)
|
|||
|
||||
this.chipset = cmp.getMachineComponent("ChipSet");
|
||||
|
||||
this.configMount = this.cmp.getMachineParm('autoMount') || this.configMount;
|
||||
|
||||
if (this.configMount) {
|
||||
if (typeof this.configMount == "string") {
|
||||
try {
|
||||
/*
|
||||
* The most likely source of any exception will be right here, where we're parsing
|
||||
* the JSON-encoded diskette data.
|
||||
*/
|
||||
this.configMount = eval("(" + this.configMount + ")");
|
||||
} catch (e) {
|
||||
Component.error("FDC auto-mount error: " + e.message + " (" + this.configMount + ")");
|
||||
this.configMount = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we didn't need auto-mount support, we could defer controller initialization until we received a powerUp() notification,
|
||||
* at which point reset() would call initController(), or restore() would restore the controller; in that case, all we'd need
|
||||
|
|
|
|||
|
|
@ -69,7 +69,12 @@
|
|||
</xsl:with-param>
|
||||
<xsl:with-param name="component" select="'machine'"/>
|
||||
<xsl:with-param name="class"><xsl:value-of select="@class"/>js</xsl:with-param>
|
||||
<xsl:with-param name="parms"><xsl:if test="@parms">,<xsl:value-of select="@parms"/></xsl:if></xsl:with-param>
|
||||
<xsl:with-param name="parms">
|
||||
<xsl:choose>
|
||||
<xsl:when test="$machineState != ''">state:"<xsl:value-of select="$machineState"/>"</xsl:when>
|
||||
<xsl:otherwise><xsl:value-of select="@parms"/></xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:with-param>
|
||||
<xsl:with-param name="url"><xsl:value-of select="@url"/></xsl:with-param>
|
||||
</xsl:call-template>
|
||||
</div>
|
||||
|
|
@ -108,9 +113,9 @@
|
|||
<xsl:otherwise><xsl:value-of select="$component"/></xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:variable>
|
||||
<xsl:variable name="componentURL">
|
||||
<xsl:variable name="machineParms">
|
||||
<xsl:choose>
|
||||
<xsl:when test="$component = 'machine'">url:'<xsl:value-of select="$url"/>'</xsl:when>
|
||||
<xsl:when test="$component = 'machine'"><xsl:value-of select="$parms"/></xsl:when>
|
||||
<xsl:otherwise/>
|
||||
</xsl:choose>
|
||||
</xsl:variable>
|
||||
|
|
@ -192,7 +197,7 @@
|
|||
<xsl:variable name="componentClass">
|
||||
<xsl:value-of select="$APPCLASS"/><xsl:text>-</xsl:text><xsl:value-of select="$component"/><xsl:text> </xsl:text><xsl:value-of select="$APPCLASS"/><xsl:text>-component</xsl:text>
|
||||
</xsl:variable>
|
||||
<div id="{$id}" class="{$componentClass}" style="{$width}{$height}{$pos}{$left}{$top}{$padding}" data-value="{$componentURL}">
|
||||
<div id="{$id}" class="{$componentClass}" style="{$width}{$height}{$pos}{$left}{$top}{$padding}" data-value="{$machineParms}">
|
||||
<xsl:if test="$component = 'machine'">
|
||||
<xsl:apply-templates select="name" mode="machine"/>
|
||||
</xsl:if>
|
||||
|
|
@ -207,7 +212,7 @@
|
|||
<xsl:apply-templates select="menu" mode="component"/>
|
||||
</xsl:if>
|
||||
<xsl:if test="$class != '' and $component != 'machine'">
|
||||
<div class="{$APPCLASS}-{$class}-object" data-value="id:'{$id}',name:'{$name}'{$comment}{$parms}"> </div>
|
||||
<div class="{$APPCLASS}-{$class}-object" data-value="{{id:'{$id}',name:'{$name}'{$comment}{$parms}}}"> </div>
|
||||
</xsl:if>
|
||||
<xsl:if test="control">
|
||||
<div class="{$APPCLASS}-controls">
|
||||
|
|
@ -355,30 +360,30 @@
|
|||
</xsl:if>
|
||||
<xsl:choose>
|
||||
<xsl:when test="@type = 'canvas'">
|
||||
<canvas class="{$APPCLASS}-binding {$APPCLASS}-canvas" width="{@width}" height="{@height}" style="-webkit-user-select:none;{$border}{$fontsize}{$style}" data-value="{$type},{$binding}"><xsl:apply-templates/></canvas>
|
||||
<canvas class="{$APPCLASS}-binding {$APPCLASS}-canvas" width="{@width}" height="{@height}" style="-webkit-user-select:none;{$border}{$fontsize}{$style}" data-value="{{{$type},{$binding}}}"><xsl:apply-templates/></canvas>
|
||||
</xsl:when>
|
||||
<xsl:when test="@type = 'button'">
|
||||
<button class="{$APPCLASS}-binding" style="-webkit-user-select:none;{$border}{$width}{$height}{$fontsize}{$style}" data-value="{$type},{$binding}"><xsl:apply-templates/></button>
|
||||
<button class="{$APPCLASS}-binding" style="-webkit-user-select:none;{$border}{$width}{$height}{$fontsize}{$style}" data-value="{{{$type},{$binding}}}"><xsl:apply-templates/></button>
|
||||
</xsl:when>
|
||||
<xsl:when test="@type = 'list'">
|
||||
<select class="{$APPCLASS}-binding" style="{$border}{$width}{$height}{$fontsize}{$style}" data-value="{$type},{$binding}">
|
||||
<select class="{$APPCLASS}-binding" style="{$border}{$width}{$height}{$fontsize}{$style}" data-value="{{{$type},{$binding}}}">
|
||||
<xsl:apply-templates select="disk|app|manifest" mode="component"/>
|
||||
</select>
|
||||
</xsl:when>
|
||||
<xsl:when test="@type = 'text'">
|
||||
<input class="{$APPCLASS}-binding" type="text" style="{$border}{$width}{$height}{$style}" data-value="{$type},{$binding}" value="{.}" autocapitalize="off" autocorrect="off"/>
|
||||
<input class="{$APPCLASS}-binding" type="text" style="{$border}{$width}{$height}{$style}" data-value="{{{$type},{$binding}}}" value="{.}" autocapitalize="off" autocorrect="off"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="@type = 'submit'">
|
||||
<input class="{$APPCLASS}-binding" type="submit" style="{$border}{$fontsize}{$style}" data-value="{$type},{$binding}" value="{.}"/>
|
||||
<input class="{$APPCLASS}-binding" type="submit" style="{$border}{$fontsize}{$style}" data-value="{{{$type},{$binding}}}" value="{.}"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="@type = 'textarea'">
|
||||
<textarea class="{$APPCLASS}-binding" style="{$border}{$width}{$height}{$style}" data-value="{$type},{$binding}" readonly="readonly"> </textarea>
|
||||
<textarea class="{$APPCLASS}-binding" style="{$border}{$width}{$height}{$style}" data-value="{{{$type},{$binding}}}" readonly="readonly"> </textarea>
|
||||
</xsl:when>
|
||||
<xsl:when test="@type = 'heading'">
|
||||
<div><xsl:value-of select="."/></div>
|
||||
</xsl:when>
|
||||
<xsl:when test="@type = 'file'">
|
||||
<form class="{$APPCLASS}-binding" data-value="{$type},{$binding}">
|
||||
<form class="{$APPCLASS}-binding" data-value="{{{$type},{$binding}}}">
|
||||
<fieldset class="{$APPCLASS}-fieldset">
|
||||
<input type="file"/>
|
||||
<input type="submit" value="Mount" disabled="true"/>
|
||||
|
|
@ -386,7 +391,7 @@
|
|||
</form>
|
||||
</xsl:when>
|
||||
<xsl:when test="@type = 'led'">
|
||||
<div class="{$APPCLASS}-binding {$APPCLASS}-{@type}" data-value="{$type},{$binding}"><xsl:value-of select="."/></div>
|
||||
<div class="{$APPCLASS}-binding {$APPCLASS}-{@type}" data-value="{{{$type},{$binding}}}"><xsl:value-of select="."/></div>
|
||||
</xsl:when>
|
||||
<xsl:when test="@type = 'separator'">
|
||||
<hr/>
|
||||
|
|
@ -398,7 +403,7 @@
|
|||
<div style="clear:both"> </div>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<div class="{$APPCLASS}-binding{$subClass} {$APPCLASS}-{@type}" style="-webkit-user-select:none;{$border}{$width}{$height}{$fontsize}{$style}" data-value="{$type},{$binding}"><xsl:apply-templates/></div>
|
||||
<div class="{$APPCLASS}-binding{$subClass} {$APPCLASS}-{@type}" style="-webkit-user-select:none;{$border}{$width}{$height}{$fontsize}{$style}" data-value="{{{$type},{$binding}}}"><xsl:apply-templates/></div>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:if test="@label">
|
||||
|
|
@ -424,7 +429,7 @@
|
|||
</xsl:if>
|
||||
</xsl:if>
|
||||
</xsl:variable>
|
||||
<option value="{@path}" data-value="{$desc}"><xsl:if test="name"><xsl:value-of select="name"/></xsl:if><xsl:if test="not(name)"><xsl:value-of select="."/></xsl:if></option>
|
||||
<option value="{@path}" data-value="{{{$desc}}}"><xsl:if test="name"><xsl:value-of select="name"/></xsl:if><xsl:if test="not(name)"><xsl:value-of select="."/></xsl:if></option>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="app[@ref]" mode="component">
|
||||
|
|
@ -447,7 +452,7 @@
|
|||
<xsl:variable name="files">
|
||||
<xsl:for-each select="file"><xsl:if test="position() = 1"><xsl:value-of select="$path"/></xsl:if><xsl:value-of select="@name"/><xsl:if test="position() != last()">;</xsl:if></xsl:for-each>
|
||||
</xsl:variable>
|
||||
<option value="{$files}" data-value="{$desc}"><xsl:value-of select="@name"/></option>
|
||||
<option value="{$files}" data-value="{{{$desc}}}"><xsl:value-of select="@name"/></option>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="manifest[@ref]" mode="component">
|
||||
|
|
@ -485,7 +490,7 @@
|
|||
</xsl:variable>
|
||||
<!-- TODO: Think about incorporating the optional "desc" tag into the disk description (see /disks/pc/tools/microsoft/c/4.00/manifest.xml) -->
|
||||
<xsl:if test="@href">
|
||||
<option value="{@href}" data-value="{$link}"><xsl:value-of select="$name"/></option>
|
||||
<option value="{@href}" data-value="{{{$link}}}"><xsl:value-of select="$name"/></option>
|
||||
</xsl:if>
|
||||
<xsl:if test="not(@href)">
|
||||
<xsl:variable name="dir">
|
||||
|
|
@ -494,7 +499,7 @@
|
|||
<xsl:variable name="files">
|
||||
<xsl:for-each select="file"><xsl:if test="position() = 1"><xsl:value-of select="$dir"/></xsl:if><xsl:value-of select="@dir"/><xsl:value-of select="."/><xsl:if test="position() != last()">;</xsl:if></xsl:for-each>
|
||||
</xsl:variable>
|
||||
<option value="{$files}" data-value="{$link}"><xsl:value-of select="$name"/></option>
|
||||
<option value="{$files}" data-value="{{{$link}}}"><xsl:value-of select="$name"/></option>
|
||||
</xsl:if>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
|
|
|
|||
Loading…
Reference in a new issue