Commands now evaluate their reference Zone at runtime, thus handling of forward references in the parser is no more needed.

svn-id: r39738
This commit is contained in:
Nicola Mettifogo 2009-03-29 12:41:00 +00:00
parent d883cb209e
commit 011b73a09b
5 changed files with 15 additions and 34 deletions

View file

@ -102,6 +102,16 @@ void CommandExec::runList(CommandList::iterator first, CommandList::iterator las
CommandPtr cmd = *first;
if (cmd->_valid && !cmd->_zone && !cmd->_zoneName.empty()) {
// try binding the command to a zone
cmd->_zone = _vm->_location.findZone(cmd->_zoneName.c_str());
cmd->_valid = cmd->_zone != 0;
}
if (!cmd->_valid) {
continue;
}
if (cmd->_flagsOn & kFlagsGlobal) {
useFlags = _globalFlags | kFlagsGlobal;
useLocalFlags = false;

View file

@ -34,6 +34,7 @@ Command::Command() {
_id = 0;
_flagsOn = 0;
_flagsOff = 0;
_valid = false;
_flags = 0;
_string = 0;

View file

@ -112,6 +112,7 @@ struct Command {
uint16 _id;
uint32 _flagsOn;
uint32 _flagsOff;
bool _valid;
Command();
~Command();
@ -119,6 +120,7 @@ struct Command {
// Common fields
uint32 _flags;
ZonePtr _zone;
Common::String _zoneName;
char* _string;
uint16 _callable;
uint16 _object;

View file

@ -204,17 +204,9 @@ protected:
void parseCommands(CommandList&);
void parseCommandFlags();
void parseCommandFlag(CommandPtr cmd, const char *flag, Table *table);
void saveCommandForward(const char *name, CommandPtr cmd);
void resolveCommandForwards();
void createCommand(uint id);
void addCommand();
struct CommandForwardReference {
char name[20];
CommandPtr cmd;
} _forwardedCommands[MAX_FORWARDS];
uint _numForwardedCommands;
void clearSet(OpcodeSet &opcodes) {
for (Common::Array<const Opcode*>::iterator i = opcodes.begin(); i != opcodes.end(); ++i)
delete *i;

View file

@ -631,10 +631,7 @@ DECLARE_COMMAND_PARSER(zone) {
createCommand(_parser->_lookup);
ctxt.cmd->_zone = _vm->_location.findZone(_tokens[ctxt.nextToken]);
if (!ctxt.cmd->_zone) {
saveCommandForward(_tokens[ctxt.nextToken], ctxt.cmd);
}
ctxt.cmd->_zoneName = _tokens[ctxt.nextToken];
ctxt.nextToken++;
parseCommandFlags();
@ -776,28 +773,10 @@ void LocationParser_ns::createCommand(uint id) {
ctxt.nextToken = 1;
ctxt.cmd = CommandPtr(new Command);
ctxt.cmd->_id = id;
ctxt.cmd->_valid = true;
}
void LocationParser_ns::saveCommandForward(const char *name, CommandPtr cmd) {
assert(_numForwardedCommands < MAX_FORWARDS);
strcpy(_forwardedCommands[_numForwardedCommands].name, name);
_forwardedCommands[_numForwardedCommands].cmd = cmd;
_numForwardedCommands++;
}
void LocationParser_ns::resolveCommandForwards() {
for (uint i = 0; i < _numForwardedCommands; i++) {
_forwardedCommands[i].cmd->_zone = _vm->_location.findZone(_forwardedCommands[i].name);
if (_forwardedCommands[i].cmd->_zone == 0) {
warning("Cannot find zone '%s' into current location script. This may be a bug in the original scripts.\n", _forwardedCommands[i].name);
}
}
_numForwardedCommands = 0;
}
void LocationParser_ns::parseCommands(CommandList& list) {
debugC(5, kDebugParser, "parseCommands()");
@ -1058,7 +1037,6 @@ DECLARE_LOCATION_PARSER(music) {
void LocationParser_ns::parse(Script *script) {
_zoneProg = 0;
_numForwardedCommands = 0;
ctxt.end = false;
_script = script;
@ -1071,8 +1049,6 @@ void LocationParser_ns::parse(Script *script) {
_parser->parseStatement();
} while (!ctxt.end);
_parser->popTables();
resolveCommandForwards();
}
void LocationParser_ns::parsePointList(PointList &list) {