simulavr-devel
[Top][All Lists]
Advanced

[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






reply via email to

[Prev in Thread] Current Thread [Next in Thread]