[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Simulavr-devel] [PATCH 08/13] AvrFactory is now a real implementation o
From: |
Onno Kortmann |
Subject: |
[Simulavr-devel] [PATCH 08/13] AvrFactory is now a real implementation of a C++ factory pattern |
Date: |
Tue, 3 Mar 2009 23:46:18 +0100 |
AVR devices register with the factory and can then be
instantiated by the factory. Makes adding new devices
easier.
Signed-off-by: Onno Kortmann <address@hidden>
---
src/Makefile.am | 2 +
src/at4433.cpp | 3 ++
src/at8515.cpp | 3 ++
src/atmega128.cpp | 3 ++
src/avrfactory.cpp | 56 ++++++++++++++++++++++++++++++---------------------
src/avrfactory.h | 18 ++++++++++++++++
src/main.cpp | 4 +--
7 files changed, 63 insertions(+), 26 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index 63a7c27..839c73f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,6 +23,7 @@ libavrsim_pp_la_SOURCES = \
atmega128.cpp \
avrdevice.cpp \
avrerror.cpp \
+ avrfactory.cpp \
avrmalloc.cpp \
decoder.cpp \
decoder_trace.cpp \
@@ -72,6 +73,7 @@ pkginclude_HEADERS = \
avrdevice.h \
avrdevice_impl.h \
avrerror.h \
+ avrfactory.h \
avrmalloc.h \
breakpoint.h \
config_deprecated.h \
diff --git a/src/at4433.cpp b/src/at4433.cpp
index 25656d0..894608d 100644
--- a/src/at4433.cpp
+++ b/src/at4433.cpp
@@ -36,7 +36,9 @@
#include "ioregs.h" //mcucr
#include "hwtimer01irq.h"
#include "hwad.h"
+#include "avrfactory.h"
+AVR_REGISTER(AT4433, AvrDevice_at90s4433);
@@ -168,3 +170,4 @@ unsigned char AvrDevice_at90s4433::GetRampz() {
void AvrDevice_at90s4433::SetRampz(unsigned char val) {
cerr << "Illegal Rampz operation in at8515 core";
}
+
diff --git a/src/at8515.cpp b/src/at8515.cpp
index b319666..ce7842d 100644
--- a/src/at8515.cpp
+++ b/src/at8515.cpp
@@ -28,6 +28,9 @@
#include "hwport.h"
#include "hwtimer01irq.h"
#include "hwwado.h"
+#include "avrfactory.h"
+
+AVR_REGISTER(AT8515, AvrDevice_at90s8515);
diff --git a/src/atmega128.cpp b/src/atmega128.cpp
index 0ece665..69df097 100644
--- a/src/atmega128.cpp
+++ b/src/atmega128.cpp
@@ -32,6 +32,9 @@
#include "hweeprom.h"
#include "hwmegatimer0123irq.h"
#include "hwwado.h"
+#include "avrfactory.h"
+
+AVR_REGISTER(ATMEGA128, AvrDevice_atmega128);
//#include "avrdevice_impl.h"
diff --git a/src/avrfactory.cpp b/src/avrfactory.cpp
index 4808288..e3cb945 100644
--- a/src/avrfactory.cpp
+++ b/src/avrfactory.cpp
@@ -21,42 +21,52 @@
*
****************************************************************************
*/
-
-#include <ctype.h> //toupper
+#include <map>
+#include <iostream>
#include "config.h"
-#include "at4433.h"
-#include "at8515.h"
-#include "atmega128.h"
#include "avrfactory.h"
using namespace std;
+typedef map<std::string, AvrFactory::AvrDeviceCreator> AVRDeviceMap;
-/* FIXME: Replace this factory with an automatically and pluggable
-factory pattern. (-> AVR devices register themselves.) */
+AVRDeviceMap devmap;
-AvrDevice* AvrFactory::makeDevice(const std::string in) {
- string c(in); //use copy to transform to lower case
- transform(c.begin(), c.end(), c.begin(), ::toupper);
-
- if (c=="AT90S4433")
- return new AvrDevice_at90s4433();
- else if (c=="AT90S8515")
- return new AvrDevice_at90s8515();
- else if (c=="ATMEGA128")
- return new AvrDevice_atmega128();
+void AvrFactory::reg(const std::string name,
+ AvrDeviceCreator create) {
+ AVRDeviceMap::iterator i=devmap.find(name);
+ if (i==devmap.end())
+ devmap[name]=create;
else {
- cerr << "Invalid device specification:" << c << endl;
- exit(1);
+ cerr << "Duplicate device specification " << name << endl;
+ exit(1);
+ }
+}
+
+AvrDevice* AvrFactory::makeDevice(const std::string in) {
+ AVRDeviceMap::iterator i=devmap.find(in);
+ if (i==devmap.end()) {
+ cerr << "Invalid device specification: " << in << endl;
+ exit(1);
}
+
+ return devmap[in]();
+}
+
+std::string AvrFactory::supportedDevices() {
+ std::string ret;
+
+ for (AVRDeviceMap::iterator i=devmap.begin();
+ i!=devmap.end(); i++)
+ ret+=i->first+"\n";
+ return ret;
}
AvrFactory& AvrFactory::instance() {
- static AvrFactory *f=0;
+ static AvrFactory *f;
if (!f) {
- f=new AvrFactory();
+ f=new AvrFactory();
+ return *f;
}
-
- return *f;
}
AvrFactory::AvrFactory() {}
diff --git a/src/avrfactory.h b/src/avrfactory.h
index 17dbe9b..3a54ecd 100644
--- a/src/avrfactory.h
+++ b/src/avrfactory.h
@@ -30,6 +30,8 @@ class AvrDevice;
class AvrFactory {
public:
+ typedef AvrDevice*(*AvrDeviceCreator)();
+
/*! Produces an AVR device according to the configuration string.
Right now, the configuration string is simply the full name of the AVR
device, like AT90S4433 or ATMEGA128.
@@ -38,9 +40,25 @@ class AvrFactory {
//! Singleton class access.
static AvrFactory& instance();
+ static std::string supportedDevices();
+
+ //! Register a creation static method with the factory
+ static void reg(const std::string name,
+ AvrDeviceCreator create);
private:
AvrFactory();
};
+#define AVR_REGISTER(name, class) \
+ struct AVRFactoryEntryMaker_ ## name { \
+ public: \
+ static AvrDevice *create_one() { \
+ return new class; \
+ } \
+ AVRFactoryEntryMaker_ ## name() { \
+ AvrFactory::reg(#name, create_one); \
+ } \
+}; \
+AVRFactoryEntryMaker_ ## name maker_ ##name;
#endif
diff --git a/src/main.cpp b/src/main.cpp
index c066d95..3e4885d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -196,9 +196,7 @@ int main(int argc, char *argv[]) {
cout << "-T --terminate <label> or <address> stops simulation
if PC runs on <label> or <address>" << endl;
cout << endl;
cout << "Supported devices:" << endl;
- cout << "AT90S4433" << endl;
- cout << "AT90S8515" << endl;
- cout << "ATMEGA128" << endl;
+ cout << AvrFactory::supportedDevices();
cout << endl;
exit(0);
--
1.5.6.5
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Simulavr-devel] [PATCH 08/13] AvrFactory is now a real implementation of a C++ factory pattern,
Onno Kortmann <=