⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 engine.cpp

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.7平台上编译为嵌入式图形界面操作系统。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/************************************************************************ Copyright (C) 2000 Trolltech AS.  All rights reserved.**** This file is part of Qtopia Environment.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "engine.h"#include <qtopia/qpeapplication.h>#include <qtopia/calc/doubleinstruction.h>#ifdef ENABLE_FRACTION#include <qtopia/calc/fractioninstruction.h>#endif#ifdef ENABLE_INTEGER#include <qtopia/calc/integerinstruction.h>#endif//#define QTEST// Bracesclass iBraceOpen:public Instruction {public:    iBraceOpen():Instruction(){};    ~iBraceOpen(){};    Data *eval(Data *);};class BraceOpen:public InstructionDescription {public:    BraceOpen();    ~BraceOpen();    Instruction *getInstruction();};BraceOpen::BraceOpen():InstructionDescription() {    instructionName = "Open brace"; // No tr    typeOne = typeTwo = type = "NONE"; // No tr    precedence = 50;};BraceOpen::~BraceOpen(){};void Engine::closeBrace () {    braceCount++;    Data *accPtr = acc;    acc = evalStack(accPtr,TRUE);    if (accPtr != acc)	delete accPtr;    updateDisplay();}Data *iBraceOpen::eval(Data *d) {    systemEngine->decBraceCount();    return d;}Instruction *BraceOpen::getInstruction() {    return new iBraceOpen();}Engine::Engine() {    // Variable initialisation    state = sStart;    emptyDataCache = mem = acc = k = 0;    kDesc = 0;    lcd = 0;#ifdef NEW_STYLE_DISPLAY    lcdPainter = 0;#endif    memMark = kMark = 0;    braceCount = previousInstructionsPrecedence = 0;    secondaryReset = FALSE;    currentType = "NONE"; // No tr    list.setAutoDelete(TRUE);    // Register the common instructions    // Double    InstructionDescription *da = new AddDoubleDouble();    registerInstruction(da);    da = new MultiplyDoubleDouble();    registerInstruction(da);    da = new SubtractDoubleDouble();    registerInstruction(da);    da = new DivideDoubleDouble();    registerInstruction(da);    da = new DoubleFactory();    registerInstruction(da);    da = new DoubleCopy();    registerInstruction(da);    da = new DoublePow();    registerInstruction(da);    da = new DoubleExp();    registerInstruction(da);    da = new DoubleSin();    registerInstruction(da);    da = new DoubleCos();    registerInstruction(da);    da = new DoubleTan();    registerInstruction(da);    da = new DoubleASin();    registerInstruction(da);    da = new DoubleACos();    registerInstruction(da);    da = new DoubleATan();    registerInstruction(da);    da = new DoubleLog();    registerInstruction(da);    da = new DoubleLn();    registerInstruction(da);    da = new DoubleOneOverX();    registerInstruction(da);    da = new DoubleFactorial();    registerInstruction(da);    da = new DoubleSquareRoot();    registerInstruction(da);    da = new DoubleCubeRoot();    registerInstruction(da);    da = new DoubleXRootY();    registerInstruction(da);    da = new DoubleSquare();    registerInstruction(da);    da = new DoubleNegate();    registerInstruction(da);#ifdef ENABLE_FRACTION    da = new FractionCopy();    registerInstruction(da);    da = new FractionFactory();    registerInstruction(da);    da = new ConvertDoubleFraction();    registerInstruction(da);    da = new AddFractionFraction();    registerInstruction(da);    da = new SubtractFractionFraction();    registerInstruction(da);    da = new MultiplyFractionFraction();    registerInstruction(da);    da = new DivideFractionFraction();    registerInstruction(da);    da = new ConvertFractionDouble();    registerInstruction(da);#endif#ifdef ENABLE_INTEGER    da = new ConvertIntDouble();    registerInstruction(da);#endif    // System    da = new BraceOpen();    registerInstruction(da);}Engine::~Engine() {    stack.clear();    iStack.clear();    dStack.clear();    delete acc;    if (mem != acc)	delete mem;};void Engine::registerInstruction(InstructionDescription *d) { #ifdef QTESTqDebug("registerInstruction - %s for %s",d->instructionName.latin1(),d->type.latin1()); // No tr#endif    InstructionDescription *tmp;    for (uint it = 0; it < list.count(); it++) {	tmp = list.at(it);	if (tmp->instructionName == d->instructionName &&		tmp->typeOne == d->typeOne &&		tmp->typeTwo == d->typeTwo)	    return;    }    list.append(d);}Instruction * Engine::resolveInstruction(QString name) {    QString type = currentType;#ifdef QTESTqDebug("resolveInstruction(%s)",name.latin1()); // No tr#endif    InstructionDescription *id = resolveDescription(name);    if (!id)	return 0;    return resolveInstruction(id);}Instruction * Engine::resolveInstruction(InstructionDescription *d) {    if (!d)	return 0;#ifdef QTESTqDebug("Searching for %s %s %s in %d", // No tr	d->instructionName.latin1(),	d->typeOne.latin1(),	d->typeTwo.latin1(),	list.count());#endif    // Create a shortlist of instructions with the same name    QList<InstructionDescription> shortList;    InstructionDescription *tmp;    uint it = 0;    for (; it < list.count(); it++) {	tmp = list.at(it);	if (tmp->instructionName == d->instructionName) 	    shortList.append(list.at(it));    }    // No instructions by that name have been found    if (!shortList.count()) {#ifdef QTESTqDebug("None found by that name"); // No tr#endif	return new Instruction();    }    Instruction *ret;    // Try to match exactly at first    for (it = 0; it < shortList.count(); it++) {	tmp = shortList.at(it);	if (tmp->typeOne == d->typeOne &&		tmp->typeTwo == d->typeTwo) {#ifdef QTESTqDebug("Matched %s %s %s",tmp->instructionName.latin1(), // No tr	tmp->typeOne.latin1(),	tmp->typeTwo.latin1());#endif	    ret = tmp->getInstruction();	    ret->num = d->num;	    return ret;	}    }#ifdef QTESTqDebug("No match found"); // No tr#endif    // Search for conversions that will let what we have work    // Eventually weighting should be here as well...    for (it = 0; it < shortList.count(); it++) {	tmp = shortList.at(it);	InstructionDescription *tmp2;	// Search for ops that only require one side to be converted	for (uint it2 = 0; it < list.count(); it2++) {	    tmp2 = list.at(it2);	    if ( tmp->typeTwo == currentType &&		    tmp2->typeOne == currentType &&		    tmp2->typeTwo == tmp->typeOne && 		    tmp2->instructionName == "Convert" ) { // No tr		// Convert		ret = tmp2->getInstruction();		ret->num = d->num;		// eval		delete ret;		// crash here...		// Now return the actual instruction		ret = tmp->getInstruction();		ret->num = d->num;		return ret;	    } else if ( tmp->typeOne == currentType &&		    tmp->typeOne == currentType &&		    tmp2->type == tmp->typeTwo &&		    tmp2->instructionName == "Convert" ) { // No tr		// Convert		ret = tmp2->getInstruction();		ret->num = d->num;		Data *accPtr = acc;		acc = ret->eval(accPtr);		if ( accPtr != acc )		    delete accPtr;		delete ret;		// Now return the actual instruction		ret = tmp->getInstruction();		ret->num = d->num;		return ret;	    }	}    }    return new Instruction();}#ifdef NEW_CONVERTint cheapestTotal;IMP *cheapestOne = 0;IMP *cheapestTwo = 0;    for (c in shortList) {	QList<instructionAndPath> allOfThem;	IMP *one = calcShortestPath(c.typeOne,tmp.typeOne);	IMP *two = calcShortestPath(c.typeTwo,tmp.typeTwo);	int totalcost = one->cost + two->cost;	if (totalcost < cheapestTotal || !cheapestOne || !cheapestTwo) {	    delete cheapestOne;	    delete cheapestTwo;	    cheapestTotal = totalcost;	    cheapestOne = one;	    cheapestTwo = two;	} else {	    delete one;	    delete two;	}}struct INP {    QList<InstructionDescription> path;    int cost;};QList<QList<InstructionDescription>> successfulPaths;	INP *calcShortestPath(QString,QString) {	// this wont work, gotta do it twice and add them remember!!!!	int cheapestCost;	QList<InstructionDescription> cheapestPath;	successfulPaths.clear();	if (birth doesnt exist) {	    InstructionDescription birth;	    birth->typeOne = "WOMB"; // No tr	    birth->typeTwo = tmp->typeOne;	    register(birth);	}	QList<InstructionDescription> life = birth;	getAPath(life);	for (i in successfulPaths) {	    if (i.cost() < cheapest) {		cheapestCost = i.cost();		cheapestPath = i;	    }	}	if (cheapestPath.isEmpty())	    return NULL;	IMP *ret = new IMP;	ret->path = cheapestPath;	ret->cost = cheapestCost;	return ret;    }QString destination;void getAPath(QList<InstructionDescription> stepsIveTaken) {    QList<InstructionDescription> exits = getAllExits(stepsIveTaken);    if (!exits.isEmpty() ) {	for (i in exits) {	    if (i->typeTwo == destination) {		successfulPaths += (stepsIveTaken + i);	    } else {		getAPath(stepsIveTaken + i);	    }	}    }}QList<InstructionDescription> Engine::getAllExits(QList<InstructionDescription> stepsIveTaken) P    QList<InstructionDescription> exits;    InstructionDescription lastStep = stepsIveTaken.last();    QString thisPlace = lastStep.typeTwo;    for (i in list) {	if ( i->typeOne == thisPlace &&		!stepsIveTaken.contains (i) ) {	    exits += i;	}    }    return exits;}#endif// Stackvoid Engine::evaluate() {    Data *accPtr = acc;    acc = evalStack(accPtr,FALSE);    if (accPtr != acc)	delete accPtr;    updateDisplay();    if ( state != sError )	state = sStart;    braceCount = 0;}Data *Engine::evalStack(Data *intermediate,bool inbrace,int p) {    if (state != sError) {	InstructionDescription *id;	Instruction *i;	while (!stack.isEmpty ()		&& (braceCount || !inbrace)		&& state != sError		&& (p <= stack.top()->precedence || p == 0) ) {	    // Pop the next instruction	    id = stack.pop();	    // Compare precedence with the next instruction on the stack	    if (!stack.isEmpty ()) {		// Recurse into next instruction if necessary		if (p) {		    if (p <= stack.top()->precedence) {			Data *numPtr = id->num;			id->num = evalStack(numPtr,inbrace,p);			if (numPtr != id->num)			    delete numPtr;		    }		} else if (id->precedence <= stack.top()->precedence) {		    Data *numPtr = id->num;		    id->num = evalStack(numPtr,inbrace,id->precedence);		    if (numPtr != id->num)			delete numPtr;		}	    }	    i = resolveInstruction(id);	    i->num = id->num;	    // Evaluate 	    Data *ptr = intermediate;	    intermediate = i->eval(ptr);	    if (ptr != intermediate) {		delete ptr;	    }	    if (i->num != intermediate && i->num != ptr) {		delete i->num;	    }	    delete i;	    delete id;	}    }    return intermediate;}// Miscellaneous functionsvoid Engine::dualReset() {    if (secondaryReset) {	hardReset();    } else {	softReset();	secondaryReset = TRUE;    }}void Engine::softReset(bool update) {#ifdef NEW_STYLE_STACK    if (dStack.isEmpty())	executeInstructionOnStack("Factory",dStack); // No tr    if (dStack.isEmpty())	qDebug("factory didnt work"); // No tr    dStack.top()->clear();#else    if (acc)	acc->clear();    else	executeInstructionOnStack("Factory",stack); // No tr#endif    state = sStart;    if (update)	updateDisplay();}void Engine::hardReset() {    stack.clear();    dStack.clear();    iStack.clear();    braceCount = 0;    secondaryReset = FALSE;    softReset();}// Input and outputInstructionDescription *Engine::resolveDescription(QString name) {    QString type = currentType;#ifdef QTESTqDebug("resolveDescription(%s, %s)",name.latin1(),type.latin1()); // No tr#endif    InstructionDescription *id;    for (uint i = 0;i < list.count();i++) {	id = list.at(i);#ifdef QTESTqDebug("  - comparing %s for %s",id->instructionName.latin1(),id->type.latin1()); // No tr#endif	if (id->instructionName == name &&		id->type == type)	    return id;    }    return 0;}#ifdef NEW_STYLE_STACKvoid Engine::immediateInstruction(QString name) {#ifdef QTESTqDebug("immediateInstruction(%s)",name.latin1()); // No tr#endif    if (state == sError || name.isEmpty())	return;    previousInstructionsPrecedence = 0;    secondaryReset = FALSE;    executeInstructionOnStack(name,stack);    updateDisplay();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -