Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Implement basic rule support.

  • Loading branch information...
commit c522d5a738f631bce768c2066f732c5362592e14 1 parent 249c7c4
@wishstudio authored
View
7 src/AbstractAlgorithm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 by Xiangyan Sun <wishstudio@gmail.com>
+ * Copyright (C) 2011,2012 by Xiangyan Sun <wishstudio@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
@@ -26,12 +26,17 @@
#include "DataChannel.h"
class CanvasPainter;
+class Rule;
class AbstractAlgorithm: public QThread, public DataReceiver
{
Q_OBJECT
public:
+ virtual ~AbstractAlgorithm() {}
+
virtual QString name() = 0;
+ virtual bool acceptRule(Rule *rule) = 0;
+
virtual int grid(const BigInteger &x, const BigInteger &y) = 0;
virtual void setGrid(const BigInteger &x, const BigInteger &y, int state) = 0;
virtual void clearGrid() = 0;
View
44 src/AlgorithmManager.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 by Xiangyan Sun <wishstudio@gmail.com>
+ * Copyright (C) 2011,2012 by Xiangyan Sun <wishstudio@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
@@ -21,21 +21,55 @@
#include "AbstractAlgorithm.h"
#include "AlgorithmManager.h"
+#include "Rule.h"
K_GLOBAL_STATIC(AlgorithmManager, globalAlgorithmManager)
+AlgorithmManager::AlgorithmManager()
+{
+ m_rule = NULL;
+ m_algorithm = NULL;
+}
+
AlgorithmManager *AlgorithmManager::self()
{
return globalAlgorithmManager;
}
+void AlgorithmManager::setRule(Rule *rule)
+{
+ if (self()->m_rule)
+ delete self()->m_rule;
+ self()->m_rule = rule;
+ if (self()->m_algorithm && !self()->m_algorithm->acceptRule(rule))
+ {
+ delete self()->m_algorithm;
+ self()->m_algorithm = NULL;
+ }
+ if (!self()->m_algorithm)
+ {
+ foreach (AbstractAlgorithmFactory *factory, self()->m_factory)
+ {
+ // TODO: Optimization
+ AbstractAlgorithm *algorithm = factory->createAlgorithm();
+ if (algorithm->acceptRule(rule))
+ {
+ connect(algorithm, SIGNAL(rectChanged()), self(), SIGNAL(rectChanged()));
+ connect(algorithm, SIGNAL(gridChanged()), self(), SIGNAL(gridChanged()));
+ self()->m_algorithm = algorithm;
+ break;
+ }
+ delete algorithm;
+ }
+ if (!self()->m_algorithm)
+ qFatal("No algorithm supports rule %s.", qPrintable(rule->string()));
+ }
+ emit self()->ruleChanged();
+}
+
void AlgorithmManager::registerAlgorithm(AbstractAlgorithmFactory *algorithmFactory)
{
self()->m_factory.append(algorithmFactory);
- // TODO
- self()->m_algorithm = algorithmFactory->createAlgorithm();
- connect(self()->m_algorithm, SIGNAL(rectChanged()), self(), SIGNAL(rectChanged()));
- connect(self()->m_algorithm, SIGNAL(gridChanged()), self(), SIGNAL(gridChanged()));
}
void AlgorithmManager::runStep()
View
9 src/AlgorithmManager.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 by Xiangyan Sun <wishstudio@gmail.com>
+ * Copyright (C) 2011,2012 by Xiangyan Sun <wishstudio@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
@@ -25,6 +25,7 @@
#include "Utils.h"
class AbstractAlgorithm;
+class Rule;
class AlgorithmManager: public QObject
{
Q_OBJECT
@@ -32,7 +33,11 @@ class AlgorithmManager: public QObject
public:
ABSTRACT_FACTORY(Algorithm)
+ AlgorithmManager();
+
static AlgorithmManager *self();
+ static Rule *rule() { return self()->m_rule; }
+ static void setRule(Rule *rule);
static AbstractAlgorithm *algorithm() { return self()->m_algorithm; }
static void registerAlgorithm(AbstractAlgorithmFactory *algorithmFactory);
@@ -40,11 +45,13 @@ public slots:
void runStep();
signals:
+ void ruleChanged();
void rectChanged();
void gridChanged();
private:
AbstractAlgorithm *m_algorithm;
+ Rule *m_rule;
QList<AbstractAlgorithmFactory *> m_factory;
};
View
2  src/CMakeLists.txt
@@ -17,7 +17,7 @@ add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
include_directories(${QT_INCLUDE} ${KDE4_INCLUDES} ${GMP_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
-set(KLife_SRCS main.cpp AbstractAlgorithm.cpp AbstractFileFormat.cpp AlgorithmManager.cpp BigInteger.cpp CanvasPainter.cpp DataChannel.cpp Editor.cpp FileFormatManager.cpp HashLife.cpp MainWindow.cpp MemoryManager.cpp RLEFormat.cpp TextStream.cpp TreeLife.cpp Utils.cpp)
+set(KLife_SRCS main.cpp AbstractAlgorithm.cpp AbstractFileFormat.cpp AlgorithmManager.cpp BigInteger.cpp CanvasPainter.cpp DataChannel.cpp Editor.cpp FileFormatManager.cpp HashLife.cpp MainWindow.cpp MemoryManager.cpp RLEFormat.cpp Rule.cpp RuleLife.cpp TextStream.cpp TreeLife.cpp Utils.cpp)
kde4_add_executable(KLife ${KLife_SRCS})
View
37 src/MainWindow.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 by Xiangyan Sun <wishstudio@gmail.com>
+ * Copyright (C) 2011,2012 by Xiangyan Sun <wishstudio@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
@@ -33,14 +33,14 @@
#include "Editor.h"
#include "FileFormatManager.h"
#include "MainWindow.h"
+#include "RuleLife.h"
MainWindow::MainWindow(QWidget *parent)
: KXmlGuiWindow(parent)
{
- AlgorithmManager::algorithm()->setInfinity(true, true);
- m_editor = new Editor(this);
- setCentralWidget(m_editor);
+ statusBar()->setSizeGripEnabled(true);
setupActions();
+
{
QWidget *form = new QWidget();
form->setStyleSheet("font-family: Monospace; font-size: 11px;");
@@ -57,7 +57,6 @@ MainWindow::MainWindow(QWidget *parent)
form->setLayout(layout);
statusBar()->addWidget(form);
}
- statusBar()->setSizeGripEnabled(true);
{
QWidget *form = new QWidget();
form->setStyleSheet("font-family: Monospace; font-size: 11px;");
@@ -74,10 +73,31 @@ MainWindow::MainWindow(QWidget *parent)
form->setLayout(layout);
statusBar()->addWidget(form);
}
+ connect(AlgorithmManager::self(), SIGNAL(gridChanged()), this, SLOT(gridChanged()));
+ {
+ QWidget *form = new QWidget();
+ form->setStyleSheet("font-family: Monospace; font-size: 11px;");
+ form->setMinimumWidth(200);
+ QFormLayout *layout = new QFormLayout();
+ layout->setMargin(0);
+ layout->setSpacing(0);
+ m_rule = new QLabel();
+ m_rule->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
+ layout->addRow(new QLabel(i18n("Rule:")), m_rule);
+ layout->addRow(new QWidget());
+ form->setLayout(layout);
+ statusBar()->addWidget(form);
+ }
+ connect(AlgorithmManager::self(), SIGNAL(ruleChanged()), this, SLOT(ruleChanged()));
+ // TODO
+ AlgorithmManager::setRule(new RuleLife("3", "23"));
+ AlgorithmManager::algorithm()->setInfinity(true, true);
gridChanged();
- connect(AlgorithmManager::self(), SIGNAL(gridChanged()), this, SLOT(gridChanged()));
+
+ m_editor = new Editor(this);
connect(m_editor, SIGNAL(coordinateChanged(const BigInteger &, const BigInteger &)), this, SLOT(coordinateChanged(const BigInteger &, const BigInteger &)));
+ setCentralWidget(m_editor);
}
void MainWindow::coordinateChanged(const BigInteger &x, const BigInteger &y)
@@ -92,6 +112,11 @@ void MainWindow::gridChanged()
m_population->setText(AlgorithmManager::algorithm()->population());
}
+void MainWindow::ruleChanged()
+{
+ m_rule->setText(QString("%1(%2)").arg(AlgorithmManager::rule()->string(), AlgorithmManager::rule()->name()));
+}
+
void MainWindow::newAction()
{
AlgorithmManager::algorithm()->clearGrid();
View
4 src/MainWindow.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 by Xiangyan Sun <wishstudio@gmail.com>
+ * Copyright (C) 2011,2012 by Xiangyan Sun <wishstudio@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
@@ -35,6 +35,7 @@ class MainWindow: public KXmlGuiWindow
public slots:
void coordinateChanged(const BigInteger &x, const BigInteger &y);
void gridChanged();
+ void ruleChanged();
void newAction();
void openAction();
@@ -43,6 +44,7 @@ public slots:
QLabel *m_coordinate_x, *m_coordinate_y;
QLabel *m_generation, *m_population;
+ QLabel *m_rule, *m_algorithm;
Editor *m_editor;
};
View
18 src/Rule.cpp
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2012 by Xiangyan Sun <wishstudio@gmail.com>
+ *
+ * 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 3, 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
View
37 src/Rule.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 by Xiangyan Sun <wishstudio@gmail.com>
+ *
+ * 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 3, 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef RULE_H
+#define RULE_H
+
+#include <QString>
+
+class Rule
+{
+public:
+ enum RuleType {Life};
+
+ virtual ~Rule() {}
+
+ virtual RuleType type() const = 0;
+ virtual QString name() const = 0;
+ virtual QString string() const = 0;
+};
+
+#endif
View
57 src/RuleLife.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2012 by Xiangyan Sun <wishstudio@gmail.com>
+ *
+ * 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 3, 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "RuleLife.h"
+
+static inline QString ruleToString(int rule)
+{
+ QString ret;
+ for (int i = 0; rule; rule >>= 1, i++)
+ if (rule & 1)
+ ret.append('0' + i);
+ return ret;
+}
+
+static inline int stringToRule(QString str)
+{
+ int ret = 0;
+ for (int i = 0; i < str.length(); i++)
+ SET_BIT(ret, str.at(i).toAscii() - '0');
+ return ret;
+}
+
+QString RuleLife::B() const
+{
+ return ruleToString(b);
+}
+
+QString RuleLife::S() const
+{
+ return ruleToString(s);
+}
+
+void RuleLife::setB(QString str)
+{
+ b = stringToRule(str);
+}
+
+void RuleLife::setS(QString str)
+{
+ s = stringToRule(str);
+}
View
56 src/RuleLife.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2012 by Xiangyan Sun <wishstudio@gmail.com>
+ *
+ * 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 3, 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef RULELIFE_H
+#define RULELIFE_H
+
+#include "Rule.h"
+#include "Utils.h"
+
+class RuleLife: public Rule
+{
+public:
+ RuleLife(QString b = "", QString s = "") { setBS(b, s); }
+
+ virtual RuleType type() const { return Rule::Life; }
+ virtual QString name() const { return "Life"; }
+ virtual QString string() const { return QString("B%1/S%2").arg(B(), S()); }
+
+ QString B() const;
+ void setB(QString str);
+ QString S() const;
+ void setS(QString str);
+
+ void setBS(QString b, QString s) { setB(b); setS(s); }
+
+ // This function is time critical
+ // So force it inlined
+ inline int nextState(int original, int neighbourCount)
+ {
+ if (original)
+ return TEST_BIT(s, neighbourCount) > 0;
+ else
+ return TEST_BIT(b, neighbourCount) > 0;
+ }
+
+private:
+ int b, s;
+};
+
+#endif
View
10 src/TreeLife.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 by Xiangyan Sun <wishstudio@gmail.com>
+ * Copyright (C) 2011,2012 by Xiangyan Sun <wishstudio@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
@@ -21,6 +21,7 @@
#include "AlgorithmManager.h"
#include "CanvasPainter.h"
+#include "RuleLife.h"
#include "TreeLife.h"
#include "Utils.h"
@@ -758,7 +759,8 @@ void TreeLife::runNode(Node *&p, Node *node, Node *up, Node *down, Node *left, N
else
n += bnode->get(sx, sy);
}
- block->set(x, y, ((n == 3) || (bnode->get(x, y) && n == 2)));
+ //block->set(x, y, ((n == 3) || (bnode->get(x, y) && n == 2)));
+ block->set(x, y, reinterpret_cast<RuleLife *>(AlgorithmManager::rule())->nextState(bnode->get(x, y), n));
block->population += block->get(x, y) > 0;
if (block->get(x, y) != bnode->get(x, y))
{
@@ -807,8 +809,11 @@ void TreeLife::runNode(Node *&p, Node *node, Node *up, Node *down, Node *left, N
}
}
+#include <QTime>
void TreeLife::run()
{
+ QTime timer;
+ timer.start();
m_running = true;
m_writeLock->lock();
if (m_root->ul->population - m_root->ul->dr->population || m_root->ur->population - m_root->ur->dl->population || m_root->dl->population - m_root->dl->ur->population || m_root->dr->population - m_root->dr->ul->population)
@@ -827,4 +832,5 @@ void TreeLife::run()
m_generation = m_generation + 1;
m_running = false;
emit gridChanged();
+ qDebug() << timer.elapsed();
}
View
5 src/TreeLife.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 by Xiangyan Sun <wishstudio@gmail.com>
+ * Copyright (C) 2011,2012 by Xiangyan Sun <wishstudio@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
@@ -25,6 +25,7 @@
#include "AbstractAlgorithm.h"
#include "BigInteger.h"
#include "MemoryManager.h"
+#include "Rule.h"
struct Block;
struct Node;
@@ -39,6 +40,8 @@ class TreeLife: public AbstractAlgorithm, private MemoryManager
virtual ~TreeLife();
virtual QString name() { return "TreeLife"; }
+ virtual bool acceptRule(Rule *rule) { return rule->type() == Rule::Life; }
+
virtual void setReceiveRect(const BigInteger &x, const BigInteger &y, quint64 w, quint64 h);
virtual void receive(DataChannel *channel);
virtual int grid(const BigInteger &x, const BigInteger &y);
View
2  src/Utils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 by Xiangyan Sun <wishstudio@gmail.com>
+ * Copyright (C) 2011,2012 by Xiangyan Sun <wishstudio@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
Please sign in to comment.
Something went wrong with that request. Please try again.