I have a speed control dial on a treadmill. I want entries limited to whole numbers, and I want to accept either numerals or words (1, 2, 3, etc. or one, two, three, etc.).
I have implemented the dial as a NumberedDial, with minSetting = 1 and maxSetting = 5.
When I enter an integer within the range 1…5, the dial accepts it. When I enter an integer outside the range, the dial refuses it as invalid.
But the only way I have found to accept words as well as numbers is to redirect the command if it has a word for an iobj, in the dobjFor(SetTo) { check() } method. But when I implement that dobjFor(SetTo), the dial accepts any integer, without regard to the min/max range. It accepts 6, for example, even though the range is 1…5.
That’s problem one.
The other more vexing problem is that the Dial will also accept fractions—up to a point—even though I’ve tried forcing the input to an integer with val = toInteger(val) in makeSetting(val)..
The dial acts on the whole number portion as one command, as though it were entered as an integer, then it apparently tries to run the same command a second time on the fractional portion and fails because of the period. This happens with or without the dobjFor(SetTo) method.
Here’s a run through with the dobjFor(SetTo) method commented out. If I put it back in, the results are the same except that the command Set dial to 6 works even though 6 is out of range.
#charset "us-ascii"
#include <tads.h>
#include "advlite.h"
versionInfo: GameID
IFID = '445C38A3-AD1B-4729-957A-F584600DE5C1'
name = 'test'
byline = 'by Jerry Ford'
htmlByline = 'by <a href="mailto:jerry.o.ford@gmail.com">
Jerry Ford</a>'
version = '1'
authorEmail = 'Jerry Ford <jerry.o.ford@gmail.com>'
desc = 'Testing dial control.'
htmlDesc = 'Testing dial control.'
;
gameMain: GameMainDef
initialPlayerChar = me
paraBrksBtwnSubcontents = nil
;
me: Actor 'me' @room
"The main man.<.p>"
isHim = true
person = 2
;
room: Room 'room'
"In the room, there is a dial.\b
<<dialCtl.desc>><.p>"
;
+ dialCtl: NumberedDial 'dial'
"The dial has settings from <<minSetting>> to <<maxSetting>>. <.p>"
minSetting = 1
maxSetting = 5
makeSetting(val)
{
inherited(val);
"The dial has been set to ";
say(val);
". <.p>";
}
dobjFor(SetTo)
{
check()
{
if(gIobj.name == 'one')
doInstead(SetTo, dialCtl, '1');
}
action()
{
inherited;
}
}
;
Any suggestions? I’m willing to give up on the input as number or word problem and just require one or the other (I have also tried implement this as a simple Dial, which takes words not integers, but the same problems occur). But that decimal problem is a, well, a problem. Not so much that I want to accept such entries, but I’m stymied on how to craft an intelligible error response (The default message I don’t understand that command is somewhat nonsensical in this context), since I cannot find a way intercept the fractional entry. The division into two commands happens before I can get to the input.
Well, I guess I could do it in a StringPreParser(), but I’m not sure how many different ways a user could set a dial, so I’m bound to miss at least one of them.
Is that my only option?
Jerry