[Avida-SVN] r2011 - in development: Avida.xcodeproj source/main

dknoester at myxo.css.msu.edu dknoester at myxo.css.msu.edu
Mon Aug 27 06:41:15 PDT 2007


Author: dknoester
Date: 2007-08-27 09:41:15 -0400 (Mon, 27 Aug 2007)
New Revision: 2011

Added:
   development/source/main/cOrgMessagePredicate.h
Modified:
   development/Avida.xcodeproj/project.pbxproj
   development/source/main/cOrgMessage.h
   development/source/main/cStats.cc
   development/source/main/cStats.h
Log:
Continued support for messaging between organisms.  Added message predicates,
an easy(-er) way to track messages that have a specific value.



Modified: development/Avida.xcodeproj/project.pbxproj
===================================================================
--- development/Avida.xcodeproj/project.pbxproj	2007-08-25 17:39:54 UTC (rev 2010)
+++ development/Avida.xcodeproj/project.pbxproj	2007-08-27 13:41:15 UTC (rev 2011)
@@ -351,6 +351,7 @@
 		1097463D0AE9606E00929ED6 /* cDeme.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cDeme.cc; sourceTree = "<group>"; };
 		1097463E0AE9606E00929ED6 /* cDeme.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cDeme.h; sourceTree = "<group>"; };
 		4201F39A0BE187F6006279B9 /* cTopology.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cTopology.h; sourceTree = "<group>"; };
+		422B64520C8305C40012C545 /* cOrgMessagePredicate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cOrgMessagePredicate.h; sourceTree = "<group>"; };
 		423335880BC067E3000DF681 /* cHardwareGX.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cHardwareGX.cc; sourceTree = "<group>"; };
 		423335890BC067E3000DF681 /* cHardwareGX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cHardwareGX.h; sourceTree = "<group>"; };
 		42490EFE0BE2472800318058 /* cGermline.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cGermline.h; sourceTree = "<group>"; };
@@ -1399,6 +1400,7 @@
 				70B0868708F49EA800FC65FE /* cOrganism.cc */,
 				70B0868308F49E9700FC65FE /* cOrganism.h */,
 				42777E5B0C7F123600AFA4ED /* cOrgMessage.h */,
+				422B64520C8305C40012C545 /* cOrgMessagePredicate.h */,
 				70B0869C08F49F4800FC65FE /* cPhenotype.cc */,
 				70B0869B08F49F3900FC65FE /* cPhenotype.h */,
 				70B0868908F49EA800FC65FE /* cPopulation.cc */,

Modified: development/source/main/cOrgMessage.h
===================================================================
--- development/source/main/cOrgMessage.h	2007-08-25 17:39:54 UTC (rev 2010)
+++ development/source/main/cOrgMessage.h	2007-08-27 13:41:15 UTC (rev 2011)
@@ -25,40 +25,27 @@
 #ifndef cOrgMessage_h
 #define cOrgMessage_h
 
-#include <iostream>
-#include <functional>
-#include <set>
-
 class cOrganism;
 
 
-/*!
+/*! This class encapsulates two unsigned integers that are sent as a "message"
+between connected organisms within an Avida population.  The label and data fields
+are these two integers, while the sending and receiving organisms are represented by
+pointers.
+
+\todo Extend to support a varying number of bytes.
 */
 class cOrgMessage
 {
-private:
-  cOrganism* m_pSender;
-  cOrganism* m_pReceiver;
-  unsigned int m_data;
-  unsigned int m_label;
-  
-  cOrgMessage() 
-    : m_pSender(NULL), m_pReceiver(NULL), m_data(0), m_label(0) {
-    }
-  
 public:
-    cOrgMessage(cOrganism* sender)
-    : m_pSender(sender), m_pReceiver(NULL), m_data(0), m_label(0) {
-    }
+  //! Constructor that takes a pointer to the sending organism.
+  cOrgMessage(cOrganism* sender) : m_pSender(sender), m_pReceiver(0), m_data(0), m_label(0) 
+  {
+    assert(m_pSender);
+  }
   
-  explicit cOrgMessage(int data, int label)
-    : m_pSender(NULL), m_pReceiver(NULL), m_data(data), m_label(label) {
-    }
-  
-  static cOrgMessage EmptyMessage() { return cOrgMessage(); }
-  
-  cOrganism* GetSender() { return m_pSender; }
-  cOrganism* GetReceiver() { return m_pReceiver; }
+  cOrganism* GetSender() const { return m_pSender; }
+  cOrganism* GetReceiver() const { return m_pReceiver; }
   void SetReceiver(cOrganism* recvr) { m_pReceiver = recvr; }
   
   unsigned int GetData() const { return m_data; }
@@ -66,51 +53,18 @@
   
   void SetData(unsigned int data) { m_data = data; }
   void SetLabel(unsigned int label) { m_label = label; }
+
+private:
+  //! Default constructor is only used internally, to support message predicates.
+  cOrgMessage() : m_pSender(0), m_pReceiver(0), m_data(0), m_label(0)
+  {
+  }
+  
+  cOrganism* m_pSender;
+  cOrganism* m_pReceiver;
+  unsigned int m_data;
+  unsigned int m_label;
 };
 
 
-///*! \brief An STL-compatible predicate on cOrgMessages.  The intent here is to
-//provide a straightforward way to track arbitrary messages *wherever* they appear
-//in the population.  The most utility can be had from message predicates if they're
-//installed into cStats (since every message goes through cStats). */
-//struct cOrgMessage_Predicate : public std::unary_function<cOrgMessage, bool> 
-//{
-//  virtual ~cOrgMessage_Predicate() { }
-//  virtual bool operator()(cOrgMessage& msg) = 0;
-//  virtual void Print(std::ostream& out) { }
-//  virtual void Reset() { }
-//};
-//
-//
-///*! A predicate that returns true and tracks the sending cell_id for messages
-//that contain the same data field as this predicate was constructed with.
-//*/
-//struct cOrgMessage_PredDataEQU : public cOrgMessage_Predicate 
-//{
-//  cOrgMessage_PredDataEQU(unsigned int data) : m_data(data) { }
-//  
-//  virtual bool operator()(cOrgMessage& msg) {
-//    if(m_data==msg.GetData()) {
-//      m_cell_ids.insert(msg.GetSender()->GetCellID());
-//    }
-//    return true;
-//  }
-//  
-//  virtual void Print(std::ostream& out) { 
-//    out << "data==" << m_data << ":{";
-//    for(std::set<int>::iterator i=m_cell_ids.begin(); i!=m_cell_ids.end(); ++i) {
-//      out << *i << ",";
-//    }
-//    out << "}";
-//  }
-//  
-//  virtual void Reset() { 
-//    m_cell_ids.clear();
-//  }
-//  
-//  unsigned int m_data;
-//  std::set<int> m_cell_ids;
-//};
-
-
 #endif

Added: development/source/main/cOrgMessagePredicate.h
===================================================================
--- development/source/main/cOrgMessagePredicate.h	                        (rev 0)
+++ development/source/main/cOrgMessagePredicate.h	2007-08-27 13:41:15 UTC (rev 2011)
@@ -0,0 +1,130 @@
+/*
+ *  cOrgMessagePredicate.h
+ *  Avida
+ *
+ *  Copyright 2005-2006 Michigan State University. All rights reserved.
+ *  Copyright 1993-2003 California Institute of Technology.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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 cOrgMessagePredicate_h
+#define cOrgMessagePredicate_h
+
+#include <iostream>
+#include <functional>
+#include <set>
+
+#include "cOrgMessage.h"
+#include "cOrganism.h"
+
+
+/*! \brief An STL-compatible predicate on cOrgMessages.  The intent here is to
+provide a straightforward way to track arbitrary messages *wherever* they appear
+in the population.  The most utility can be had from message predicates if they're
+installed into cStats (since every message goes through cStats). */
+struct cOrgMessagePredicate : public std::unary_function<cOrgMessage, bool> 
+{
+  virtual ~cOrgMessagePredicate() { }
+  virtual bool operator()(const cOrgMessage& msg) = 0;
+  virtual void Print(std::ostream& out) { }
+  virtual void Reset() { }
+};
+
+
+/*! A predicate that returns true and tracks the sending cell_id for messages
+that contain the same data field as this predicate was constructed with.
+*/
+struct cOrgMessagePred_DataEQU : public cOrgMessagePredicate 
+{
+  cOrgMessagePred_DataEQU(unsigned int data) : m_data(data) { }
+  
+  virtual bool operator()(const cOrgMessage& msg) {
+    if(m_data==msg.GetData()) {
+      m_cell_ids.insert(msg.GetSender()->GetCellID());
+    }
+    return true;
+  }
+  
+  virtual void Print(std::ostream& out) { 
+    out << "data==" << m_data << ":{";
+    for(std::set<int>::iterator i=m_cell_ids.begin(); i!=m_cell_ids.end(); ++i) {
+      out << *i << ",";
+    }
+    out << "}";
+  }
+  
+  virtual void Reset() { 
+    m_cell_ids.clear();
+  }
+  
+  unsigned int m_data;
+  std::set<int> m_cell_ids;
+};
+
+
+/*! A predicate that returns true and tracks the label and data field for messages
+that contain a sink as the receiver.
+*/
+struct cOrgMessagePred_SinkReceiverEQU : public cOrgMessagePredicate {
+  cOrgMessagePred_SinkReceiverEQU(unsigned int data) : m_data(data) { }
+  
+  virtual bool operator()(const cOrgMessage& msg) {
+    if(m_data==(unsigned int)msg.GetReceiver()->GetCellID()) {
+      m_cell_ids.insert(msg.GetData());
+//      cWorld* w = msg.GetSender()->getWorld();
+      /*      int i = w->GetPopulation().GetCell(289).GetRandomCellID();
+      if(msg.GetData() == i) {
+        std::cout<<"289 = "<< i<<endl;
+      }*/
+    }
+    return true;
+  }
+  
+  virtual void print(std::ostream& out) { 
+//    cPopulationCell::t_id_map& ids = cPopulationCell::GetRandomCellIDMap();
+//    int badMSGs = 0;
+//    
+//    out << "data==" << m_data << ":{";
+//    for(std::set<int>::iterator i=m_cell_ids.begin(); i!=m_cell_ids.end(); ++i) {
+//      int x,y;
+//      //check if # is ID and log cell location and count bad messages
+//      if(cPopulationCell::IsRandomCellID(*i)) {
+//        cPopulationCell* cell = ids.find(*i)->second;
+//        cell->GetPosition(x, y);
+//        out << x <<" "<< y << ",";
+//        m_cell_ids_total_good.insert(cell->GetRandomCellID());
+//      } else {
+//        badMSGs++;
+//        //        out << *i << ",";
+//      }
+//    }
+//    //write # bad messages in last slot
+//    out << badMSGs;
+//    out << "} "<<m_cell_ids_total_good.size();
+  }
+  
+  virtual void reset() { 
+    m_cell_ids.clear();
+  }
+  
+  unsigned int m_data;
+  std::set<int> m_cell_ids;
+  std::set<int> m_cell_ids_total_good;
+};
+
+
+#endif

Modified: development/source/main/cStats.cc
===================================================================
--- development/source/main/cStats.cc	2007-08-25 17:39:54 UTC (rev 2010)
+++ development/source/main/cStats.cc	2007-08-27 13:41:15 UTC (rev 2011)
@@ -35,6 +35,7 @@
 #include "cWorldDriver.h"
 #include "tDataEntry.h"
 #include "cOrgMessage.h"
+#include "cOrgMessagePredicate.h"
 
 #include "functions.h"
 
@@ -1034,4 +1035,48 @@
 the organism that this message was sent to. */
 void cStats::SentMessage(const cOrgMessage& msg)
 {
+  // Check to see if this message matches any of our predicates.
+  for(message_pred_ptr_list::iterator i=m_message_predicates.begin(); 
+      i!=m_message_predicates.end(); ++i) {
+    (**i)(msg); // Predicate is responsible for tracking info about messages.
+  }  
 }
+
+
+/*! This method adds a message predicate to the list of all predicates.  Each predicate
+in the list is evaluated for every sent message.
+
+NOTE: cStats does NOT own the predicate pointer!  (It DOES NOT delete them!)
+*/
+void cStats::AddMessagePredicate(cOrgMessagePredicate* predicate)
+{
+  m_message_predicates.push_back(predicate);
+}
+
+
+/*! This method prints information contained within all active message predicates.
+
+about  specific messages that are being tracked.
+The messages that are being tracked are setup by the AddTrackedMessage method below.
+
+The format of this log file is:
+<update> \
+<predicate>:{<cell_id>,...}...
+*/
+void cStats::PrintPredicatedMessages(const cString& filename)
+{
+  cDataFile& df = m_world->GetDataFile(filename);
+  df.WriteColumnDesc("update [update]");
+  df.WriteColumnDesc("predicate:{p_info,...}...");
+  df.FlushComments();
+  
+  df.WriteAnonymous(m_update);
+  std::ofstream& out = df.GetOFStream();
+  for(message_pred_ptr_list::iterator i=m_message_predicates.begin();
+      i!=m_message_predicates.end(); ++i) {
+    (*i)->Print(out);
+    (*i)->Reset();
+    out << " ";
+  }
+  df.Endl();  
+}

Modified: development/source/main/cStats.h
===================================================================
--- development/source/main/cStats.h	2007-08-25 17:39:54 UTC (rev 2010)
+++ development/source/main/cStats.h	2007-08-27 13:41:15 UTC (rev 2011)
@@ -29,6 +29,7 @@
 #include <cassert>
 #include <fstream>
 #include <iostream>
+#include <vector>
 
 #ifndef defs_h
 #include "defs.h"
@@ -66,6 +67,7 @@
 class cInjectGenotype;
 class cWorld;
 class cOrgMessage;
+class cOrgMessagePredicate;
 
 class cStats
 {
@@ -615,13 +617,24 @@
   void PrintSleepData(const cString& filename);
   
   // -------- Messaging support --------
-protected:
+public:
+  //! Type for a list of pointers to message predicates.
+  typedef std::vector<cOrgMessagePredicate*> message_pred_ptr_list;
   
-    
-public:
   //! Called for every message successfully sent anywhere in the population.
   void SentMessage(const cOrgMessage& msg);
+  //! Adds a predicate that will be evaluated for each message.
+  void AddMessagePredicate(cOrgMessagePredicate* predicate);
+  //! Prints information regarding messages that "passed" their predicate.
+  void PrintPredicatedMessages(const cString& filename);
+
+protected:
+  /*! List of all active message predicates.  The idea here is that the predicates,
+  rather than cStats / cOrgMessage / etc., do the tracking of particular messages
+  of interest. */
+  message_pred_ptr_list m_message_predicates;
   // -------- End messaging support --------
+  
 };
 
 




More information about the Avida-cvs mailing list