📄 scheduler.cc
字号:
//// Copyright (c) 2003 by Istv醤 V醨adi//// This file is part of dxr3Player, a DVD player written specifically // for the DXR3 (aka Hollywood+) decoder card.// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program 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 General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA//------------------------------------------------------------------------------#include "Scheduler.h"#include "Processor.h"#include "TargetPosition.h"#include "util/Log.h"//------------------------------------------------------------------------------using dvd::vm::Scheduler;using dvd::vm::Scheduler;//------------------------------------------------------------------------------// These inline functions are put here to avoid a circular dependency// of the headers Scheduler.h and Processor.h. But since// these functions are used internally only, it should not cause any trouble.//------------------------------------------------------------------------------inline void Scheduler::push(const Command* command){ if (nextCommandSlot<commandStackSize) { commandStack[nextCommandSlot++] = command; } else { addFirstPlayPGC(); }}//------------------------------------------------------------------------------inline const Scheduler::Command* Scheduler::pop(){ return (nextCommandSlot>0) ? commandStack[--nextCommandSlot] : 0;}//------------------------------------------------------------------------------inline void Scheduler::breakSet(){ instructionSet.reset(); instructionPointer = 0;}//------------------------------------------------------------------------------inline void Scheduler::step(){ const Instruction* instruction = instructionSet[instructionPointer++]; if (instruction!=0) processor.process(instruction); else breakSet();}//------------------------------------------------------------------------------inline void Scheduler::setPosition(const Position& position){ processor.setPosition(position);}//------------------------------------------------------------------------------//------------------------------------------------------------------------------void Scheduler::InstructionSetCommand::execute() const{ scheduler.instructionSet = instructionSet; scheduler.instructionPointer = instructionPointer; scheduler.step();}//------------------------------------------------------------------------------//------------------------------------------------------------------------------void Scheduler::StepCommand::execute() const{ scheduler.step();}//------------------------------------------------------------------------------//------------------------------------------------------------------------------void Scheduler::GotoCommand::execute() const{ scheduler.instructionPointer = instructionPointer; scheduler.step();}//------------------------------------------------------------------------------//------------------------------------------------------------------------------void Scheduler::BreakCommand::execute() const{ scheduler.breakSet();}//------------------------------------------------------------------------------//------------------------------------------------------------------------------void Scheduler::SetPositionCommand::execute() const{ scheduler.setPosition(position);}//------------------------------------------------------------------------------//------------------------------------------------------------------------------void Scheduler::run(){ const Command* command = 0; while( (command=pop())!=0 ) { command->execute(); delete command; }}//------------------------------------------------------------------------------void Scheduler::addInstructionSet(const Instruction* instructions, size_t length, size_t insPointer){// printf("Added instruction set:\n");// InstructionSet(instructions, length).print(stdout, 2); push(new InstructionSetCommand(*this, InstructionSet(instructions, length), insPointer));}//------------------------------------------------------------------------------bool Scheduler::addCellCommand(const Position& position){ PGC pgc = position.getPGC(); if (!pgc) { Log::fatal("dvd::vm::Scheduler::addCellCommand: Cannot add cell command since PGC is invalid\n"); return false; } unsigned cellNo = position.getCellNumber(); if (cellNo<1 || cellNo>pgc.getNumberOfCells()) return false; CellPlaybackInfo cellPlaybackInfo = pgc.getCellPlaybackInfo(cellNo); unsigned cellCommandNo = cellPlaybackInfo.getCellCommandNumber(); CommandTable commandTable = pgc.getCommandTable(); if (commandTable && cellCommandNo>=1 && cellCommandNo<=commandTable.getNumberOfCellCommands()) { addInstructionSet(commandTable.getCellCommands() + cellCommandNo - 1); return true; } return false;}//------------------------------------------------------------------------------bool Scheduler::addPGCPreCommands(const Position& position){ PGC pgc = position.getPGC(); if (!pgc) { Log::fatal("dvd::vm::Scheduler::addPGCPreCommands: Cannot add PGC pre-commands since PGC is invalid\n"); return false; } CommandTable commandTable = pgc.getCommandTable(); if (pgc.isEmpty()) { // FIXME: add something to go to the next PGC addPGCPostCommands(position); } if (commandTable) { addInstructionSet(commandTable.getPreCommands(), commandTable.getNumberOfPreCommands()); } return true;}//------------------------------------------------------------------------------bool Scheduler::addStartPGC(const Position& position){ flush(); if (addPGCPreCommands(position)) { addSetPosition(position); return true; } else { addFirstPlayPGC(); return false; }}//------------------------------------------------------------------------------bool Scheduler::addPGCPostCommands(const Position& position){ PGC pgc = position.getPGC(); if (!pgc) { Log::fatal("dvd::vm::Scheduler::addPGCPostCommands: Cannot add PGC post-commands since PGC is invalid\n"); return false; } CommandTable commandTable = pgc.getCommandTable(); if (commandTable) { addInstructionSet(commandTable.getPostCommands(), commandTable.getNumberOfPostCommands()); return commandTable.getNumberOfPostCommands() > 0; } else { return false; }}//------------------------------------------------------------------------------void Scheduler::addStep(){ push(new StepCommand(*this));}//------------------------------------------------------------------------------void Scheduler::addGoto(size_t insPointer){ push(new GotoCommand(*this, insPointer-1));}//------------------------------------------------------------------------------void Scheduler::addBreak(){ push(new BreakCommand(*this));}//------------------------------------------------------------------------------void Scheduler::addSetPosition(const Position& position){ push(new SetPositionCommand(*this, position));}//------------------------------------------------------------------------------void Scheduler::addFirstPlayPGC(){ flush(); TargetPosition position(processor.state.getPosition()); position.enterFirstPlayPGC(); addPGCPreCommands(position); addSetPosition(position);}//------------------------------------------------------------------------------void Scheduler::flush(){ while(nextCommandSlot>0) { delete commandStack[--nextCommandSlot]; }}//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -