[Avida-cvs] [Avida2-svn] r345 - in trunk: Avida2.xcodeproj source source/main source/tools
brysonda@myxo.css.msu.edu
brysonda at myxo.css.msu.edu
Sun Oct 16 07:32:23 PDT 2005
Author: brysonda
Date: 2005-10-16 10:32:22 -0400 (Sun, 16 Oct 2005)
New Revision: 345
Added:
trunk/source/main/cAvidaConfig.cc
trunk/source/main/cAvidaConfig.h
Modified:
trunk/Avida2.xcodeproj/project.pbxproj
trunk/source/defs.hh
trunk/source/main/cConfig.cc
trunk/source/tools/cStringUtil.cc
trunk/source/tools/cStringUtil.h
Log:
Add cAvidaConfig class, implementing the new configuration method. Nothing uses it, yet.
Modified: trunk/Avida2.xcodeproj/project.pbxproj
===================================================================
--- trunk/Avida2.xcodeproj/project.pbxproj 2005-10-16 12:29:36 UTC (rev 344)
+++ trunk/Avida2.xcodeproj/project.pbxproj 2005-10-16 14:32:22 UTC (rev 345)
@@ -26,6 +26,10 @@
700E2B87085DE54400CF158A /* viewer in CopyFiles */ = {isa = PBXBuildFile; fileRef = 700E2B83085DE50C00CF158A /* viewer */; };
701384340900A45B0087ED2E /* organism.smtx in CopyFiles */ = {isa = PBXBuildFile; fileRef = 701384330900A45B0087ED2E /* organism.smtx */; };
701384350900A45B0087ED2E /* organism.smtx in CopyFiles */ = {isa = PBXBuildFile; fileRef = 701384330900A45B0087ED2E /* organism.smtx */; };
+ 7013846109028B3E0087ED2E /* cAvidaConfig.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7013845F09028B3E0087ED2E /* cAvidaConfig.h */; };
+ 7013846209028B3E0087ED2E /* cAvidaConfig.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7013846009028B3E0087ED2E /* cAvidaConfig.cc */; };
+ 7013846309028B3E0087ED2E /* cAvidaConfig.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7013845F09028B3E0087ED2E /* cAvidaConfig.h */; };
+ 7013846409028B3E0087ED2E /* cAvidaConfig.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7013846009028B3E0087ED2E /* cAvidaConfig.cc */; };
702D4EFE08DA5341007BA469 /* cAvidaDriver_Analyze.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702D4EF908DA5341007BA469 /* cAvidaDriver_Analyze.cc */; };
702D4EFF08DA5341007BA469 /* cAvidaDriver_Base.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702D4EFA08DA5341007BA469 /* cAvidaDriver_Base.cc */; };
702D4F0008DA5341007BA469 /* cAvidaDriver_Population.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702D4EFB08DA5341007BA469 /* cAvidaDriver_Population.cc */; };
@@ -330,6 +334,7 @@
700E2B7C085DE50C00CF158A /* genesis.smt in CopyFiles */,
700E2B7D085DE50C00CF158A /* inst_set.smt in CopyFiles */,
701384340900A45B0087ED2E /* organism.smtx in CopyFiles */,
+ 7013846109028B3E0087ED2E /* cAvidaConfig.h in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -355,6 +360,7 @@
706D33110854A7D700D7DC8F /* genesis.smt in CopyFiles */,
706D33280854A90D00D7DC8F /* inst_set.smt in CopyFiles */,
701384350900A45B0087ED2E /* organism.smtx in CopyFiles */,
+ 7013846309028B3E0087ED2E /* cAvidaConfig.h in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -364,6 +370,8 @@
700E28CF0859FFD700CF158A /* tObjectFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tObjectFactory.h; sourceTree = "<group>"; };
700E2B83085DE50C00CF158A /* viewer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = viewer; sourceTree = BUILT_PRODUCTS_DIR; };
701384330900A45B0087ED2E /* organism.smtx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = organism.smtx; sourceTree = "<group>"; };
+ 7013845F09028B3E0087ED2E /* cAvidaConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cAvidaConfig.h; sourceTree = "<group>"; };
+ 7013846009028B3E0087ED2E /* cAvidaConfig.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cAvidaConfig.cc; sourceTree = "<group>"; };
702D4EF208DA5328007BA469 /* cAvidaDriver_Analyze.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cAvidaDriver_Analyze.h; sourceTree = "<group>"; };
702D4EF308DA5328007BA469 /* cAvidaDriver_Base.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cAvidaDriver_Base.h; sourceTree = "<group>"; };
702D4EF408DA5328007BA469 /* cAvidaDriver_Population.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cAvidaDriver_Population.h; sourceTree = "<group>"; };
@@ -2164,6 +2172,8 @@
DCC311090762539E008F7A48 /* primitive.cc */,
DCC3112E0762539E008F7A48 /* unit_testsuites */,
70B085D108F48C9400FC65FE /* nSpecies.h */,
+ 7013845F09028B3E0087ED2E /* cAvidaConfig.h */,
+ 7013846009028B3E0087ED2E /* cAvidaConfig.cc */,
);
path = main;
sourceTree = "<group>";
@@ -3178,6 +3188,7 @@
70B0894808F7630100FC65FE /* cStringUtil.cc in Sources */,
70B08B9208FB2E6B00FC65FE /* cTools.cc in Sources */,
70B08B9308FB2E6B00FC65FE /* cWeightedIndex.cc in Sources */,
+ 7013846209028B3E0087ED2E /* cAvidaConfig.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3299,6 +3310,7 @@
70B0893708F7630100FC65FE /* cStringUtil.cc in Sources */,
70B08B9408FB2E6B00FC65FE /* cTools.cc in Sources */,
70B08B9508FB2E6B00FC65FE /* cWeightedIndex.cc in Sources */,
+ 7013846409028B3E0087ED2E /* cAvidaConfig.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Modified: trunk/source/defs.hh
===================================================================
--- trunk/source/defs.hh 2005-10-16 12:29:36 UTC (rev 344)
+++ trunk/source/defs.hh 2005-10-16 14:32:22 UTC (rev 345)
@@ -8,9 +8,7 @@
#ifndef DEFS_HH
#define DEFS_HH
-#ifndef VERSION
#define VERSION "2.3.1"
-#endif
#define VERSION_TAG "Padawan"
Added: trunk/source/main/cAvidaConfig.cc
===================================================================
--- trunk/source/main/cAvidaConfig.cc 2005-10-16 12:29:36 UTC (rev 344)
+++ trunk/source/main/cAvidaConfig.cc 2005-10-16 14:32:22 UTC (rev 345)
@@ -0,0 +1,257 @@
+/*
+ * cAvidaConfig.cc
+ * Avida2
+ *
+ * Created by David on 10/16/05.
+ * Copyright 2005 Michigan State University. All rights reserved.
+ *
+ */
+
+#include "cAvidaConfig.h"
+
+#include <fstream>
+#include "defs.hh"
+#include "cInitFile.h"
+
+tList<cAvidaConfig::cBaseConfigGroup> cAvidaConfig::global_group_list;
+
+cAvidaConfig::cBaseConfigEntry::cBaseConfigEntry(const cString & _name,
+ const cString & _type, const cString & _def, const cString & _desc)
+: config_name(_name)
+, type(_type)
+, default_value(_def)
+, description(_desc)
+, use_overide(true)
+{
+ // If the default value was originally a string, it will begin and end with
+ // quotes. We should make sure to remove those.
+ if (default_value[0] == '"') {
+ cout << "Removing quotes from " << default_value << endl;
+ default_value = default_value.Substring(1, default_value.GetSize() - 2);
+ cout << "...now " << default_value << endl;
+ }
+}
+
+
+cAvidaConfig::cAvidaConfig()
+{
+ group_list.Transfer(global_group_list);
+}
+
+cAvidaConfig::~cAvidaConfig()
+{
+}
+
+void cAvidaConfig::Load(const cString & filename)
+{
+ // Load the contents from the file.
+ cInitFile init_file(filename);
+ init_file.Load();
+ init_file.Compress();
+ init_file.Close();
+
+ // Loop through all groups, then all entrys, and try to load each one.
+ tListIterator<cBaseConfigGroup> group_it(group_list);
+ cBaseConfigGroup * cur_group;
+ while ((cur_group = group_it.Next()) != NULL) {
+
+ // Loop through entries for this group...
+ tListIterator<cBaseConfigEntry> entry_it(cur_group->GetEntryList());
+ cBaseConfigEntry * cur_entry;
+ while ((cur_entry = entry_it.Next()) != NULL) {
+ const cString keyword = cur_entry->GetName();
+ const cString default_val = cur_entry->GetDefault();
+ cur_entry->LoadString( init_file.ReadString(keyword, default_val) );
+ }
+ }
+}
+
+void cAvidaConfig::Print(const cString & filename)
+{
+ ofstream fp(filename);
+
+ // Print out the generic header, including the version ID.
+ fp << "#############################################################################" << endl
+ << "# This file includes all the basic run-time defines for Avida." << endl
+ << "# For more information, see doc/config.html" << endl
+ << "#############################################################################" << endl
+ << endl
+ << "VERSION_ID " << VERSION << " # Do not change this value."
+ << endl;
+
+ // Loop through the groups, and print out all of the variables.
+
+ tListIterator<cBaseConfigGroup> group_it(group_list);
+ cBaseConfigGroup * cur_group;
+ while ((cur_group = group_it.Next()) != NULL) {
+ // Print out the group name...
+ fp << endl;
+ fp << "### " << cur_group->GetName() << " ###" << endl;
+
+ // If we have a comment about the current group, include it. Make sure
+ // to allow multi-line comments.
+ cStringList group_desc(cur_group->GetDesc(), '\n');
+ while (group_desc.GetSize() > 0) {
+ fp << "# " << group_desc.Pop() << endl;
+ }
+
+ // Print out everything for this group...
+ tListIterator<cBaseConfigEntry> entry_it(cur_group->GetEntryList());
+
+ // First, figure out the widest entry so we know where to put comments.
+ int max_width = 0;
+ cBaseConfigEntry * cur_entry;
+ while ((cur_entry = entry_it.Next()) != NULL) {
+ int cur_width = cur_entry->GetName().GetSize() +
+ cur_entry->GetDefault().GetSize() + 1;
+ if (cur_width > max_width) max_width = cur_width;
+ }
+
+ // Now, make a second pass printing everything.
+ entry_it.Reset();
+ while ((cur_entry = entry_it.Next()) != NULL) {
+ int cur_width = cur_entry->GetName().GetSize() +
+ cur_entry->GetDefault().GetSize() + 1;
+ // Print the variable and its setting...
+ fp << cur_entry->GetName() << " " << cur_entry->GetDefault();
+
+ // Print some spaces before the description.
+ for (int i = cur_width; i < max_width; i++) fp << " ";
+
+ // Print the first line of the description.
+ // @CAO Again, we should allow multi-line comments....
+ if (cur_entry->GetDesc().GetSize() == 0) {
+ fp << " # " << endl;
+ } else {
+ cStringList cur_desc(cur_entry->GetDesc(), '\n');
+ fp << " # " << cur_desc.Pop() << endl;
+ while (cur_desc.GetSize() > 0) {
+ for (int i = 0; i < max_width; i++) fp << " ";
+ fp << " # " << cur_desc.Pop() << endl;
+ }
+ }
+
+ }
+ }
+}
+
+void cAvidaConfig::Status()
+{
+ cout << "Config contains " << group_list.GetSize() << " groups." << endl;
+
+ tListIterator<cBaseConfigGroup> group_it(group_list);
+ cBaseConfigGroup * cur_group;
+ while ((cur_group = group_it.Next()) != NULL) {
+ cout << "Group \"" << cur_group->GetName()
+ << "\" has " << cur_group->GetEntryList().GetSize()
+ << " settings." << endl;
+ }
+}
+
+void cAvidaConfig::GenerateOverides()
+{
+ ofstream fp("config_overrides.h");
+
+ // Print out a header for the top of the file.
+ fp << "/****************************************************************************" << endl;
+ fp << " * This is an automatically generated file. This file will overide any *" << endl;
+ fp << " * values set by the user at runtime. When Avida is compiled using these *" << endl;
+ fp << " * overides, it will reduce the flexibility of the user, but will increase *" << endl;
+ fp << " * the speed at which Avida runs. *" << endl;
+ fp << " * *" << endl;
+ fp << " * To use this file, include the compiler option -DOVERRIDE_CONFIGS *" << endl;
+ fp << " ***************************************************************************/" << endl;
+ fp << endl;
+
+ // Loop through all of the groups, printing the classes representing that
+ // group followed by the classes representing the individual settings.
+ tListIterator<cBaseConfigGroup> group_it(group_list);
+ cBaseConfigGroup * cur_group;
+ while ((cur_group = group_it.Next()) != NULL) {
+ fp << "/**********************************************" << endl;
+ fp << " * Group: " << cur_group->GetName() << endl;
+ fp << " * Description: " << cur_group->GetDesc() << endl;
+ fp << " **********************************************/" << endl;
+ fp << endl;
+
+ fp << "class cGroup_" << cur_group->GetName()
+ << " : public cBaseConfigGroup {" << endl;
+ fp << "public:" << endl;
+ fp << " cGroup_" << cur_group->GetName() << "()" << endl;
+
+ // Pay special attention to multi-line group descriptions.
+ fp << " : cBaseConfigGroup(\""
+ << cur_group->GetName() << "\", \"";
+ cStringList group_desc(cur_group->GetDesc(), '\n');
+ fp << group_desc.Pop();
+ while (group_desc.GetSize() > 0) {
+ fp << "\\n";
+ fp << group_desc.Pop();
+ }
+ fp << "\") { ; }" << endl;
+ fp << "} " << cur_group->GetName() << ";" << endl;
+ fp << endl;
+
+ // Print out the entries for this group...
+ tListIterator<cBaseConfigEntry> entry_it(cur_group->GetEntryList());
+ cBaseConfigEntry * cur_entry;
+ while ((cur_entry = entry_it.Next()) != NULL) {
+ const cString & cur_name = cur_entry->GetName();
+ const cString & cur_default = cur_entry->GetDefault();
+ const cString & cur_type = cur_entry->GetType();
+ cStringList cur_desc(cur_entry->GetDesc(), '\n');
+ fp << "// Entry: " << cur_name << endl;
+ fp << "// Description: ";
+ if (cur_desc.GetSize() > 0) fp << cur_desc.GetLine(0);
+ fp << endl;
+ for (int i = 1; i < cur_desc.GetSize(); i++) {
+ fp << "// " << cur_desc.GetLine(i) << endl;
+ }
+ fp << "class cEntry_" << cur_name
+ << " : public cBaseConfigEntry {" << endl;
+ fp << "private:" << endl;
+ fp << " " << cur_type << " value;" << endl;
+ fp << "public:" << endl;
+ fp << " void LoadString(const cString & str_value) {" << endl;
+ fp << " value = cStringUtil::Convert(str_value, value);" << endl;
+ fp << " }" << endl;
+ fp << " cEntry_" << cur_name << "() : cBaseConfigEntry(\""
+ << cur_name << "\", \"" << cur_type << "\", \""
+ << cur_default << "\", \"";
+ if (cur_desc.GetSize() > 0) { fp << cur_desc.Pop(); }
+ while (cur_desc.GetSize() > 0) {
+ fp << "\\n" << cur_desc.Pop();
+ }
+ fp << "\") {" << endl;
+ fp << " LoadString(GetDefault());" << endl;
+ fp << " global_group_list.GetLast()->AddEntry(this);" << endl;
+ fp << " }" << endl;
+
+ // This section will vary depending on if we are making this variable
+ // a constant.
+ if (cur_entry->GetUseOveride() == true) {
+ // For string types we must enclose the value in quotes.
+ if (cur_type == "cString") {
+ fp << " " << cur_type << " Get() const { return \""
+ << cur_entry->AsString() << "\"; }" << endl;
+ } else {
+ fp << " " << cur_type << " Get() const { return "
+ << cur_entry->AsString() << "; }" << endl;
+ }
+ fp << " void Set(" << cur_type
+ << " in_value) { cerr << \"ERROR: resetting value for constant setting '" << cur_name << "'\" << endl; }" << endl;
+ } else {
+ fp << " " << cur_type << " Get() const { return value; }" << endl;
+ fp << " void Set(" << cur_type
+ << " in_value) { value = in_value; }" << endl;
+ }
+
+ fp << " cString AsString() { return cStringUtil::Convert(value); }" << endl;
+ fp << "} " << cur_name << ";" << endl;
+ fp << endl;
+ }
+
+ // Skip an extra line between groups
+ fp << endl;
+ }
+}
Added: trunk/source/main/cAvidaConfig.h
===================================================================
--- trunk/source/main/cAvidaConfig.h 2005-10-16 12:29:36 UTC (rev 344)
+++ trunk/source/main/cAvidaConfig.h 2005-10-16 14:32:22 UTC (rev 345)
@@ -0,0 +1,300 @@
+/*
+ * cAvidaConfig.h
+ * Avida2
+ *
+ * Created by David on 10/16/05.
+ * cConfig class created by Charles.
+ * Copyright 2005 Michigan State University. All rights reserved.
+ *
+ */
+
+#ifndef CONFIG_HH
+#define CONFIG_HH
+
+// This class is designed to easily allow the construction of a dynamic
+// configuration object that will handle the loading and management of all
+// variables declared at runtime. It will also allow for some variables to
+// be transparently set at compile time and allow the programmer to easily
+// add in new settings with a single line of code.
+
+#include <iostream>
+
+#include "cString.h"
+#include "cStringUtil.h"
+#include "tList.h"
+
+using namespace std;
+
+
+// The following macro will create all of the code needed to include an
+// entry for a new setting in the configuration.
+//
+// To step through what we are doing:
+// 1 - Load in four variables representing the setting name, its type, its
+// default value, and a brief description of what its for. The description
+// should be a string, enclosed in quotes.
+// 2 - Build a new class using the setting name with the prefix cEntry_
+// This class will contain all of the info about this setting, and will
+// be derived from the cBaseConfigEntry class so that we may easily refer
+// to any of these dynamically created classes.
+// 3 - Create a private value for this setting.
+// 4 - Create a LoadString() method to load the settings in from a string.
+// 5 - Create a constructor that passes all of the information to the base
+// class that it can manage to.
+// 6 - Initialize the value of this setting to its default.
+// 7 - Insert the newly built object into the full list of settings objects.
+// 8 - Create Get() and Set() methods to act as accessors.
+// 9 - Setup a method to return the value of this setting as a string.
+// 10 - Declare a variable of this class's type to use in the future. Since
+// accessors were declared above, we can refer to this setting by the
+// setting name inside of config.
+
+#define CONFIG_ADD_VAR(NAME, TYPE, DEFAULT, DESC) /* 1 */ \
+class cEntry_ ## NAME : public cBaseConfigEntry { /* 2 */ \
+private: \
+ TYPE value; /* 3 */ \
+public: \
+ void LoadString(const cString & str_value) { /* 4 */ \
+ value = cStringUtil::Convert(str_value, value); \
+ } \
+ cEntry_ ## NAME() : cBaseConfigEntry(#NAME, #TYPE, #DEFAULT, DESC) {/* 5 */ \
+ LoadString(GetDefault()); /* 6 */ \
+ global_group_list.GetLast()->AddEntry(this); /* 7 */ \
+ } \
+ TYPE Get() const { return value; } /* 8 */ \
+ void Set(TYPE in_value) { value = in_value; } \
+ cString AsString() { return cStringUtil::Convert(value); } /* 9 */ \
+} NAME /* 10 */ \
+
+
+// Now we're going to make another macro to deal with groups. This time its
+// a bit simpler since there is only one type of group. The reason that we
+// want to make a new class for each new group is so that we can set default
+// values for the class with its name and description. Otherwise we would
+// need to send those parameters in elsewhere.
+
+#define CONFIG_ADD_GROUP(NAME, DESC) \
+class cGroup_ ## NAME : public cBaseConfigGroup { \
+public: \
+ cGroup_ ## NAME() : cBaseConfigGroup(#NAME, DESC) { ; } \
+} NAME \
+
+class cAvidaConfig {
+private:
+ // The cBaseConfigEntry class is a bass class for all configuration entries.
+ // It is used to manage the various types of entries in a dynamic fashion.
+ class cBaseConfigEntry {
+private:
+ const cString config_name; // Name of this setting
+ const cString type; // What type does this entry return?
+ cString default_value; // Value to use if not found in config file.
+ const cString description; // Explaination of the use of this setting
+
+ // If we automatically regenerate this file to optimize its performace,
+ // we can explicitly build some of these classes to return constant
+ // values (not changeable at run time). Should this instance be one of
+ // those classes?
+ bool use_overide;
+public:
+ cBaseConfigEntry(const cString & _name, const cString & _type,
+ const cString & _def, const cString & _desc);
+ virtual ~cBaseConfigEntry() { ; }
+
+ virtual void LoadString(const cString & str_value) = 0;
+
+ const cString & GetName() { return config_name; }
+ const cString & GetType() { return type; }
+ const cString & GetDefault() { return default_value; }
+ const cString & GetDesc() { return description; }
+ bool GetUseOveride() { return use_overide; }
+
+ virtual cString AsString() = 0;
+ };
+
+ // The cBaseConfigGroup class is a bass class for objects that collect the
+ // configuration entries into logical groups.
+ class cBaseConfigGroup {
+private:
+ cString group_name;
+ cString description;
+ tList<cBaseConfigEntry> entry_list;
+public:
+ cBaseConfigGroup(const cString & _name, const cString & _desc)
+ : group_name(_name), description(_desc) { global_group_list.PushRear(this); }
+ ~cBaseConfigGroup() { ; }
+
+ const cString & GetName() { return group_name; }
+ const cString & GetDesc() { return description; }
+ tList<cBaseConfigEntry> & GetEntryList() { return entry_list; }
+
+ void AddEntry(cBaseConfigEntry * _entry) { entry_list.PushRear(_entry); }
+ };
+
+ // We need to keep track of all configuration groups and the entry objects
+ // that they contain. To do this, we create a global list of groups that
+ // all groups must register themselves in. A new entry object will always
+ // use the last group in the list, so we merely need to make sure to keep
+ // things in order. When all configuration objects are built, we then
+ // transfer the list to the local cAvidaConfig object (which occurs in the
+ // constructor.)
+ static tList<cBaseConfigGroup> global_group_list;
+ tList<cBaseConfigGroup> group_list;
+
+public:
+ cAvidaConfig();
+ ~cAvidaConfig();
+
+#ifdef OVERRIDE_CONFIG
+#include "config_overrides.h"
+#else
+ CONFIG_ADD_GROUP(ARCH_GROUP, "Architecture Variables");
+ CONFIG_ADD_VAR(MAX_UPDATES, int, -1, "Maximum updates to run experiment (-1 = no limit)");
+ CONFIG_ADD_VAR(MAX_GENERATIONS, int, -1, "Maximum generations to run experiment (-1 = no limit)");
+ CONFIG_ADD_VAR(END_CONDITION_MODE, int, 0, "End run when ...\n0 = MAX_UPDATES _OR_ MAX_GENERATIONS is reached\n1 = MAX_UPDATES _AND_ MAX_GENERATIONS is reached");
+ CONFIG_ADD_VAR(WORLD_X, int, 100, "Width of the Avida world");
+ CONFIG_ADD_VAR(WORLD_Y, int, 100, "Height of the Avida world");
+ CONFIG_ADD_VAR(WORLD_GEOMETRY, int, 2, "1 = Bounded Grid\n2 = Torus");
+ CONFIG_ADD_VAR(NUM_DEMES, int, 0, "Number of independed groups in the population; 0=off");
+ CONFIG_ADD_VAR(RANDOM_SEED, int, 0, "Random number seed (0 for based on time)");
+ CONFIG_ADD_VAR(HARDWARE_TYPE, int, 0, "0 = Original CPUs\n1 = New, Stack-based CPUs\n2 = Newer -- Stacks, Memory, Threading");
+
+ CONFIG_ADD_GROUP(CONFIG_FILE_GROUP, "Configuration Files");
+ CONFIG_ADD_VAR(DEFAULT_DIR, cString, "../work/", "Directory in which config files are found");
+ CONFIG_ADD_VAR(INST_SET, cString, "inst_set.default", "File containing instruction set");
+ CONFIG_ADD_VAR(EVENT_FILE, cString, "events.cfg", "File containing list of events during run");
+ CONFIG_ADD_VAR(ANALYZE_FILE, cString, "analyze.cfg", "File used for analysis mode");
+ CONFIG_ADD_VAR(ENVIRONMENT_FILE, cString, "environment.cfg", "File that describes the environment");
+ CONFIG_ADD_VAR(START_CREATURE, cString, "organism.default", "Organism to seed the soup");
+
+ CONFIG_ADD_GROUP(REPRODUCTION_GROUP, "Birth and Death");
+ CONFIG_ADD_VAR(BIRTH_METHOD, int, 4, "0 = Replace random organism in neighborhood\n1 = Replace oldest organism in neighborhood\n2 = Replace largest Age/Merit in neighborhood\n3 = Place only in empty cells in neighborhood\n4 = Replace random from population (Mass Action)\n5 = Replace oldest in entire population (like Tierra)\n6 = Replace random within deme");
+ CONFIG_ADD_VAR(PREFER_EMPTY, int, 1, "Are empty cells given preference in offsping placement?");
+ CONFIG_ADD_VAR(DEATH_METHOD, int, 2, "0 = Never die of old age.\n1 = Die when inst executed = AGE_LIMIT (+deviation)\n2 = Die when inst executed = length*AGE_LIMIT (+dev)");
+ CONFIG_ADD_VAR(AGE_LIMIT, int, 20, "Modifies DEATH_METHOD");
+ CONFIG_ADD_VAR(AGE_DEVIATION, int, 0, "Creates a distribution around AGE_LIMIT");
+ CONFIG_ADD_VAR(ALLOC_METHOD, int, 0, "(Orignal CPU Only)\n0 = Allocated space is set to default instruction.\n1 = Set to section of dead genome (Necrophilia)\n2 = Allocated space is set to random instruction.");
+ CONFIG_ADD_VAR(DIVIDE_METHOD, int, 1, "0 = Divide leaves state of mother untouched.\n1 = Divide resets state of mother (after the divide, we have 2 children)\n2 = Divide resets state of current thread only(does not touch possible parasite threads)");
+ CONFIG_ADD_VAR(GENERATION_INC_METHOD, int, 1, "0 = Only the generation of the child is\n increased on divide.\n1 = Both the generation of the mother and child are\n increased on divide (good with DIVIDE_METHOD 1).");
+ CONFIG_ADD_VAR(RECOMBINATION_PROB, double, 1.0, "probability that recombination will happen when div-sex is used");
+ CONFIG_ADD_VAR(MODULE_NUM, int, 0, "number of modules in the genome");
+ CONFIG_ADD_VAR(CONT_REC_REGS, int, 1, "are (modular) recombination regions continuous");
+ CONFIG_ADD_VAR(CORESPOND_REC_REGS, int, 1, "are (modular) recombination regions swapped at random or with corresponding ones, by location");
+ CONFIG_ADD_VAR(TWO_FOLD_COST_SEX, int, 0, "1 = only one recombined offspring is born.\n2 = both offspring are born");
+ CONFIG_ADD_VAR(SAME_LENGTH_SEX, int, 0, "0 = recombine with any genome\n1 = only recombine w/ same length");
+
+ CONFIG_ADD_GROUP(DIVIDE_GROUP, "Divide Restrictions");
+ CONFIG_ADD_VAR(CHILD_SIZE_RANGE, double, 2.0, "Maximal differential between child and parent sizes.");
+ CONFIG_ADD_VAR(MIN_COPIED_LINES, double, 0.5, "Code fraction which must be copied before divide.");
+ CONFIG_ADD_VAR(MIN_EXE_LINES, double, 0.5, "Code fraction which must be executed before divide.");
+ CONFIG_ADD_VAR(REQUIRE_ALLOCATE, int, 1, "(Origianl CPU Only) Is a an allocate required before a divide? (0/1)");
+ CONFIG_ADD_VAR(REQUIRED_TASK, int, -1, "Task ID required for successful divide.");
+ CONFIG_ADD_VAR(IMMUNITY_TASK, int, -1, "Task providing immunity from the required task.");
+ CONFIG_ADD_VAR(REQUIRED_REACTION, int, -1, "Reaction ID required for successful divide.");
+ CONFIG_ADD_VAR(DIE_PROB, double, 0.0, "probability of death when 'die' instruction is executed");
+
+ CONFIG_ADD_GROUP(MUTATION_GROUP, "Mutations");
+ CONFIG_ADD_VAR(POINT_MUT_PROB, double, 0.0, "Mutation rate (per-location per update)");
+ CONFIG_ADD_VAR(COPY_MUT_PROB, double, 0.0075, "Mutation rate (per copy)");
+ CONFIG_ADD_VAR(INS_MUT_PROB, double, 0.0, "Insertion rate (per site, applied on divide)");
+ CONFIG_ADD_VAR(DEL_MUT_PROB, double, 0.0, "Deletion rate (per site, applied on divide)");
+ CONFIG_ADD_VAR(DIV_MUT_PROB, double, 0.0, "Mutation rate (per site, applied on divide)");
+ CONFIG_ADD_VAR(DIVIDE_MUT_PROB, double, 0.0, "Mutation rate (per divide)");
+ CONFIG_ADD_VAR(DIVIDE_INS_PROB, double, 0.05, "Insertion rate (per divide)");
+ CONFIG_ADD_VAR(DIVIDE_DEL_PROB, double, 0.05, "Deletion rate (per divide)");
+ CONFIG_ADD_VAR(PARENT_MUT_PROB, double, 0.0, "Per-site, in parent, on divide");
+ CONFIG_ADD_VAR(SPECIAL_MUT_LINE, int, -1, "If this is >= 0, ONLY this line is mutated");
+
+ CONFIG_ADD_GROUP(REVERSION_GROUP, "Mutation Reversion\nThese slow down avida a lot, and should be set to 0.0 normally.");
+ CONFIG_ADD_VAR(REVERT_FATAL, double, 0.0, "Should any mutations be reverted on birth?");
+ CONFIG_ADD_VAR(REVERT_DETRIMENTAL, double, 0.0, " 0.0 to 1.0; Probability of reversion.");
+ CONFIG_ADD_VAR(REVERT_NEUTRAL, double, 0.0, "");
+ CONFIG_ADD_VAR(REVERT_BENEFICIAL, double, 0.0, "");
+ CONFIG_ADD_VAR(STERILIZE_FATAL, double, 0.0, "Should any mutations clear (kill) the organism?");
+ CONFIG_ADD_VAR(STERILIZE_DETRIMENTAL, double, 0.0, "");
+ CONFIG_ADD_VAR(STERILIZE_NEUTRAL, double, 0.0, "");
+ CONFIG_ADD_VAR(STERILIZE_BENEFICIAL, double, 0.0, "");
+ CONFIG_ADD_VAR(FAIL_IMPLICIT, int, 0, "Should copies that failed *not* due to mutations\nbe eliminated?");
+
+ CONFIG_ADD_GROUP(TIME_GROUP, "Time Slicing");
+ CONFIG_ADD_VAR(AVE_TIME_SLICE, int, 30, "Ave number of insts per org per update");
+ CONFIG_ADD_VAR(SLICING_METHOD, int, 2, "0 = CONSTANT: all organisms get default...\n1 = PROBABILISTIC: Run _prob_ proportional to merit.\n2 = INTEGRATED: Perfectly integrated deterministic.");
+ CONFIG_ADD_VAR(SIZE_MERIT_METHOD, int, 0, "0 = off (merit is independent of size)\n1 = Merit proportional to copied size\n2 = Merit prop. to executed size\n3 = Merit prop. to full size\n4 = Merit prop. to min of executed or copied size\n5 = Merit prop. to sqrt of the minimum size");
+ CONFIG_ADD_VAR(TASK_MERIT_METHOD, int, 1, "0 = No task bonuses\n1 = Bonus just equals the task bonus");
+ CONFIG_ADD_VAR(MAX_CPU_THREADS, int, 1, "Number of Threads a CPU can spawn");
+ CONFIG_ADD_VAR(THREAD_SLICING_METHOD, int, 0, "Formula for and organism's thread slicing -> 1 + (num_organism_threads-1) * THREAD_SLICING_METHOD.\n0 = One thread executed per time slice.\n1 = All threads executed each time slice.\n");
+ CONFIG_ADD_VAR(MAX_LABEL_EXE_SIZE, int, 1, "Max nops marked as executed when labels are used");
+ CONFIG_ADD_VAR(BASE_SIZE_MERIT, int, 100, "Base merit when size is *not* used");
+ CONFIG_ADD_VAR(DEFAULT_BONUS, double, 1.0, "The bonus an organism gets before it has completed any tasks");
+ CONFIG_ADD_VAR(MERIT_TIME, int, 0, "0 = Merit Calculated when task completed\n1 = Merit Calculated on Divide");
+ CONFIG_ADD_VAR(MERIT_GIVEN, double, 0.0, "Fraction of merit donated with 'donate' command");
+ CONFIG_ADD_VAR(MERIT_RECEIVED, double, 0.0, "Multiplier of merit given with 'donate' command");
+ CONFIG_ADD_VAR(MAX_DONATE_KIN_DIST, int, -1, "Limit on distance of relation for donate; -1=no max");
+ CONFIG_ADD_VAR(MAX_DONATE_EDIT_DIST, int, -1, "Limit on genetic (edit) distance for donate; -1=no max");
+ CONFIG_ADD_VAR(MAX_DONATES, int, 1000000, "Limit on number of donates organisms are allowed.");
+
+ CONFIG_ADD_GROUP(GENEOLOGY_GROUP, "Geneology");
+ CONFIG_ADD_VAR(TRACK_MAIN_LINEAGE, int, 1, "Keep all ancestors of the active population?\n0=no, 1=yes, 2=yes,w/sexual population");
+ CONFIG_ADD_VAR(THRESHOLD, int, 3, "Number of organisms in a genotype needed for it\n to be considered viable.");
+ CONFIG_ADD_VAR(GENOTYPE_PRINT, int, 0, "0/1 (off/on) Print out all threshold genotypes?");
+ CONFIG_ADD_VAR(GENOTYPE_PRINT_DOM, int, 0, "Print out a genotype if it stays dominant for\n this many updates. (0 = off)");
+ CONFIG_ADD_VAR(SPECIES_THRESHOLD, int, 2, "max failure count for organisms to be same species");
+ CONFIG_ADD_VAR(SPECIES_RECORDING, int, 0, "1 = full, 2 = limited search (parent only)");
+ CONFIG_ADD_VAR(SPECIES_PRINT, int, 0, "0/1 (off/on) Print out all species?");
+ CONFIG_ADD_VAR(TEST_CPU_TIME_MOD, int, 20, "Time allocated in test CPUs (multiple of length)");
+
+ CONFIG_ADD_GROUP(LOG_GROUP, "Log Files");
+ CONFIG_ADD_VAR(LOG_CREATURES, bool, 0, "0/1 (off/on) toggle to print file.");
+ CONFIG_ADD_VAR(LOG_GENOTYPES, int, 0, "0 = off, 1 = print ALL, 2 = print threshold ONLY.");
+ CONFIG_ADD_VAR(LOG_THRESHOLD, bool, 0, "0/1 (off/on) toggle to print file.");
+ CONFIG_ADD_VAR(LOG_SPECIES, bool, 0, "0/1 (off/on) toggle to print file.");
+ CONFIG_ADD_VAR(LOG_LANDSCAPE, bool, 0, "0/1 (off/on) toggle to print file.");
+
+ CONFIG_ADD_GROUP(VIEWER_GROUP, "Viewer Settings");
+ CONFIG_ADD_VAR(VIEW_MODE, int, 0, "Initial viewer screen");
+
+ CONFIG_ADD_GROUP(LINEAGE_GROUP, "Lineage\nNOTE: This should probably be called \"Clade\"\nThis one can slow down avida a lot. It is used to get an idea of how\noften an advantageous mutation arises, and where it goes afterwards.\nLineage creation options are. Works only when LOG_LINEAGES is set to 1.\n 0 = manual creation (on inject, use successive integers as lineage labels).\n 1 = when a child's (potential) fitness is higher than that of its parent.\n 2 = when a child's (potential) fitness is higher than max in population.\n 3 = when a child's (potential) fitness is higher than max in dom. lineage\n*and* the child is in the dominant lineage, or (2)\n 4 = when a child's (potential) fitness is higher than max in dom. lineage\n(and that of its own lineage)\n 5 = same as child's (potential) fitness is higher than that of the\n currently dominant organism, and also than that of any organism\n currently in the same lineage.\n 6 = when a child's (potential) f!
itness is higher than any organism\n currently in the same lineage.\n 7 = when a child's (potential) fitness is higher than that of any\n organism in its line of descent");
+ CONFIG_ADD_VAR(LOG_LINEAGES, bool, 0, "");
+ CONFIG_ADD_VAR(LINEAGE_CREATION_METHOD, int, 0, "");
+#endif
+
+ void Load(const cString & filename);
+ void Print(const cString & filename);
+ void Status();
+
+ void GenerateOverides();
+};
+
+
+
+
+
+// Concept:
+// Setup #define to build class that will manage the specific variable inside
+// of config, as well as any other necessary functions. Each class must have
+// * A Get() method
+// * A Set(in_value) method
+// * A Load(config file) method
+// * Get Name
+// * Get Desc
+//
+// User must provide in the definition:
+// object name
+// genesis ID
+// default value
+// description
+// type?
+//
+//
+// We must also register the class so that the Load function can be called
+// automatically when the config class is built. (as well as name and help
+// and such can be looked up as needed.)
+//
+// This will all be easiest if we have an abstract base class.
+//
+// If we want to specify constant values (as opposed to using the dynamic
+// loading from a file), the #define will be rebuilt as nothing and a separate
+// header will be included that defines each class manually. This will only
+// happen
+
+
+#endif
Modified: trunk/source/main/cConfig.cc
===================================================================
--- trunk/source/main/cConfig.cc 2005-10-16 12:29:36 UTC (rev 344)
+++ trunk/source/main/cConfig.cc 2005-10-16 14:32:22 UTC (rev 345)
@@ -209,8 +209,6 @@
"Task ID required for successful divide.");
div_group->Add(immunity_task, "-1", "IMMUNITY_TASK",
"Task providing immunity from the required task.");
- div_group->Add(immunity_task, "-1", "IMMUNITY_TASK",
- "Task providing immunity from the required task.");
div_group->Add(required_reaction, "-1", "REQUIRED_REACTION",
"Reaction ID required for successful divide.");
div_group->Add(die_prob, "0", "DIE_PROB",
Modified: trunk/source/tools/cStringUtil.cc
===================================================================
--- trunk/source/tools/cStringUtil.cc 2005-10-16 12:29:36 UTC (rev 344)
+++ trunk/source/tools/cStringUtil.cc 2005-10-16 14:32:22 UTC (rev 345)
@@ -288,3 +288,24 @@
{
return in_string.AsDouble();
}
+
+cString cStringUtil::Convert(const cString & in_string)
+{
+ return in_string;
+}
+
+cString cStringUtil::Convert(bool in_bool)
+{
+ if (in_bool == false) return "0";
+ return "1";
+}
+
+cString cStringUtil::Convert(int in_int)
+{
+ return Stringf("%d", in_int);
+}
+
+cString cStringUtil::Convert(double in_double)
+{
+ return Stringf("%f", in_double);
+}
Modified: trunk/source/tools/cStringUtil.h
===================================================================
--- trunk/source/tools/cStringUtil.h 2005-10-16 12:29:36 UTC (rev 344)
+++ trunk/source/tools/cStringUtil.h 2005-10-16 14:32:22 UTC (rev 345)
@@ -52,6 +52,10 @@
static bool Convert(const cString & in_string, bool type_bool);
static int Convert(const cString & in_string, int type_int);
static double Convert(const cString & in_string, double type_double);
+ static cString Convert(const cString & in_string);
+ static cString Convert(bool in_bool);
+ static cString Convert(int in_int);
+ static cString Convert(double in_double);
};
#endif
More information about the Avida-cvs
mailing list