Wednesday, December 5, 2012

Link To Resume

Resume

I know this is pretty rough, but just trying to get this up.

GenericRPG

The Design

The idea of GenericRPG was to make a text based game that parodied a lot of rpgs. 

The Developement

My first semester of my freshman year I had the option of either making a game in a 2d editor call 'Project Fun' or making a text based game. When considering my options of trying to make a game in an editor that used C++ or the text game that was to be ANSI C my choice was pretty straightforward.

Being that I had never coded before starting school this project was really built as I  learned. If you are to step through it I am sure you will be able to tell when I first learned about structs, as about half of the project is depended on passing 10+ varaibles in function calls.

The Code

Sadly this code is horrid, but that is an important thing to note. I really love this project just because of how far I have came in less than 4 years.

Time Trouble

The Design

Time Trouble was modeled to be top down puzzle game inspired by Braid.

The Developement

The Code

Audio Analysis

Talking about that here.

parChord

The Design

The Development

The Code

3D Studio Max Exporter


The entirety of the 3ds Max Exporter can be found here.

This exporter took the level build in 3ds Max and compiled it down to javascript. This was then used in the game as a level file.

Project Derelict


The Design

Project Derelict was developed to be a 1v1 sci-fi fps. The thing that we thought would really offset us from other games was the integration of biometrics. The gameplay was to have two characters  The first being a human in a spacesuit and the other to be a mad/crazy alien. As the human the player's goal was simple: enter the alien derelict spaceship, retrieve the power sources and get back to their shuttle and escape, oh and not die. As the alien the player was to hunt down the human and get 'rid of them.' 

The human's advantages was their ranged laser gun and their protective suit. The alien had radar, speed, and regeneration pods.

The Development

Over the course of a year myself 4 other programmers, 2 designers, 5 artists, and an hardware engineering  graduate put out time, energy, and passion into making this project a reality. Over the course of the year much of the design changed as we ran into technical and design hurdles we had not anticipated. Video of our final project can be found at www.projectderelict.com

The Code

My two tasks on this project were 3D positional audio and a 3ds Max Exporter that allowed for the entire level to be build in Max then exported to our custom JavaScript.

The entirety of the 3ds Max Exporter can be found here. I would strongly discourage anyone to view this. Bellow is to be a lessons learned on Max Script and writing this kind of thing.

Postmortem ~**~*~~~~*****


An explanation of the 3D positional audio can be found here.

Another thing I did was a wrapper interface for AntTweakBar to JavaScript. While the code isn't too exciting it was really fun to write and the design pattern I went with was really exciting. You may notice some oddity with how arguments are being passed, unfortunately our C++ to JavaScript binding didn't have a way to handle Enumerations for a good portion of the development.



/*****************************************************************************/
/*!

\author Branden Gee
\par contributors:

\file AntBar.cpp
\par Project: Derelict
\par "All content c 2010 DigiPen (USA) Corporation, all rights reserved.
\date 7/26/2011
\brief
  #BLANK_DESCRIPTION

*/
/*****************************************************************************/
#include "Precompiled.h"
#include "AntBar.h"
#include "Core.h"
#include "WindowSystem.h"
#include 
static std::string napkin;
static char buffer[1024];
static char tempbuffer[1024];
//Yes I know this function is dangerous. Don't call it out of order :P
char* inttostring(int i)
{
 if(!i)
 {
  buffer[0] = '0';
  buffer[1] = 0;
  return buffer;
 }

 buffer[0] = 0;
 int negative = 0;
 if(i < 0)
 {
  negative = 1;
  i *= -1;
 }
 int temp = i;
 int digitPlaces = 0;
 while(temp)
 {
  tempbuffer[digitPlaces++] = temp%10;
  temp /= 10;
 }

 temp = 0;
 buffer[digitPlaces + negative] = 0;
 while(digitPlaces)
 {
  int indexA = negative + temp;
  int indexB = (digitPlaces - 1);
  buffer[indexA] = tempbuffer[indexB] + '0';
  --digitPlaces;
  ++temp;
 }
 if(negative)
  buffer[0] = '-';

 return buffer;
}



char* ntoa(float i)
{
 sprintf(buffer, "%f", i);
 return buffer;
}
char* ntoa(unsigned char i)
{
 sprintf(buffer, "%c", i);
 return buffer;
}
static unsigned char AntBarName[5] = {1,1,1,0,0};
static int AntBarNameId = 0;
void IdHelperIncrement(int pos)
{
 //If at max
 if(pos < 0)
 {
  for(size_t i = 0; i < sizeof(AntBarName) - 2; ++i)
  {
   AntBarName[i] = 1;
  }
  AntBarName[sizeof(AntBarName) - 2] = 0;
 }

 //Increment
 ++AntBarName[pos];
 if(AntBarName[pos] == '\'')
  ++AntBarName[pos];

 if(!AntBarName[pos])
 {
  IdHelperIncrement(pos - 1);
  ++AntBarName[pos];
 }
}

const char* GetNextId()
{
 //IdHelperIncrement(sizeof(AntBarName) - 2);
 //return (char*)AntBarName;
 return inttostring(AntBarNameId++);
}

namespace Framework
{
 static Sint32 windowWidth;
 static Sint32 windowHeight;
 // static unsigned nextWindowID = 0;

 AntBar::AntBar( void )
 {
  enumerations = new AntBarEnumerationManager();
 }

 void AntBar::Initialize()
 {
  TwInit(TW_OPENGL, NULL);
  CoreHas(WindowSystem)->GetWindowDimentions(windowWidth, windowHeight);
  TwWindowSize(windowWidth, windowHeight);
  TwDefine(" TW_HELP visible='false' ");
  DrawAntBar = true;

 }

 AntBarWindow* AntBar::CreateAntWindow( const std::string& windowName )
 {
  if(!NameToId.count(windowName))
  {
   NameToId[windowName] = IdToObject.size();
   IdToObject[IdToObject.size()] = new AntBarWindow(windowName);
  }
  else
  {
   ConsoleMessage("The Window Name /'%s/' already exists", windowName.c_str());
  }
  return IdToObject[IdToObject.size() - 1];
 }

#ifdef ENABLE_DEBUG_DIAGNOSTICS
 static bool notAdded = true;
#endif
 void AntBar::Update( float dt )
 {
#ifdef ENABLE_DEBUG_DIAGNOSTICS
  if(notAdded)
  {
   notAdded = false;
  }
#endif
  UnusedVariable(dt);
  if(DrawAntBar)
   TwDraw();
 }

 void AntBar::InterpretMessage( const MessagePointer& msg )
 {
  UnusedVariable(msg);
 }

 AntBar::~AntBar()
 {
  for(std::map::iterator iter = IdToObject.begin(); iter != IdToObject.end(); ++iter)
  {
   delete iter->second;
  }
  delete enumerations;
 }

 AntBarWindow& AntBar::WindowById( unsigned id )
 {

  return *(IdToObject.find(id)->second);

 }

 AntBarWindow& AntBar::WindowByName( const std::string& windowName )
 {
  unsigned temp = NameToId.find(windowName)->second;
  return WindowById(temp);
 }

 typeOfVariable* AntBar::CreateSettings()
 {
  return new typeOfVariable;
 }


 AntBarWindow::AntBarWindow( const std::string& name )
 {
  IdName = name;
  UnderHoodId = GetNextId();
  mybar = TwNewBar(UnderHoodId.c_str());
  napkin = "\'";
  napkin += UnderHoodId;
  napkin += "\'  label=\'";
  napkin += name;
  napkin += "\'";
  if(!TwDefine(napkin.c_str()))
   ConsoleMessage("%s", TwGetLastError());

  baseLabel = new AntBarGroup(UnderHoodId, "", std::vector(), std::vector(), mybar);
  baseLabel->IdVal = 0;
 }

 void AntBarWindow::SetVisability( const bool isVisable )
 {
  napkin = " \'";
  napkin += UnderHoodId;
  napkin += "\'";
  napkin += " visible=";
  if(isVisable)
  {
   napkin += "true ";
  }
  else
  {
   napkin += "false ";
  }
  TwDefine(napkin.c_str());
 }

 void AntBarWindow::SetPosition( const int x, const int y )
 {
  napkin = " \'";
  napkin += UnderHoodId;
  napkin += "\' ";
  napkin += " position=\'";
  napkin += inttostring(x);
  napkin += ' ';
  napkin += inttostring(y);
  napkin += "\' ";
  TwDefine(napkin.c_str());
 }

 void AntBarWindow::SetTitle(const std::string& title)
 {
  napkin = " \'";
  napkin += UnderHoodId;
  napkin += "\' ";
  napkin += " label=\'";
  napkin += title;
  napkin += "\' ";
  TwDefine(napkin.c_str());
 }

 void AntBarWindow::SetSize( const int x, const int y )
 {
  napkin = " \'";
  napkin += UnderHoodId;
  napkin += "\' ";
  napkin += " size=\'";
  napkin += inttostring(x);
  napkin += ' ';
  napkin += inttostring(y);
  napkin += "\' ";
  TwDefine(napkin.c_str());
 }

 void AntBarWindow::SetValuesWidth( const unsigned w )
 {
  std::string width;
  napkin = " \'";
  napkin += UnderHoodId;
  napkin += "\' ";
  napkin += " valueswidth=\'";
  if(w)
   napkin += inttostring(w);
  else
   napkin += "fit";
  napkin += "\' ";
  TwDefine(napkin.c_str());
 }

 void AntBarWindow::SetOpacity(const unsigned opac)
 {
  std::ostringstream o;
  o << " \'"
    << UnderHoodId
    << "\' "
    << " alpha=\'"
    << opac
    << "\' ";
  TwDefine(o.str().c_str());
 }

 void AntBarWindow::SetColor( Uint32 r, Uint32 g, Uint32 b )
 {
  std::ostringstream o;
  o << " \'"
    << UnderHoodId
    << "\' "
    << " color=\'"
    << r
    << " "
    << g
    << " "
    << b
    << "\' ";
  TwDefine(o.str().c_str());
 }

 void AntBarWindow::SetAlwaysOnTop(bool onTop)
 {
  std::ostringstream o;
  o << " \'"
    << UnderHoodId
    << "\' "
    << " alwaysTop=\'"
    << ((onTop)? "true" : "false")
    << "\' ";
  TwDefine(o.str().c_str());
 }

 AntBarVariable* AntBarGroup::CreateVariable(const std::string& name, typeOfVariable* Settings)
 {
  AntBarVariable* baby = new AntBarVariable(mybar, name, Settings, WindowName);
  VarNameToId[baby->UnderHoodId] = VarIdToVariable.size();
  VarIdToVariable[VarIdToVariable.size()] = baby;
  //Add Variable to Group
  if(IdName == "")
   return baby;

  std::string labelMaker = "\'";
  labelMaker += WindowName;
  labelMaker += "\'/\'";
  labelMaker += baby->UnderHoodId;
  labelMaker += "\' group=\'";
  labelMaker += UnderHoodId;
  labelMaker += "\'";
  TwDefine(labelMaker.c_str());
  //Rename Group
  labelMaker = "\'";
  labelMaker += WindowName;
  labelMaker += "\'/\'";
  labelMaker += UnderHoodId;
  labelMaker += "\'  label=\'";
  labelMaker += IdName;
  labelMaker += "\'";
  TwDefine(labelMaker.c_str());

  labelIdsAboveMe.push_back(UnderHoodId);
  labelNamesAboveMe.push_back(IdName);
  for(int i = labelIdsAboveMe.size() - 1; i > 1; --i)
  {
   //Add group to group
   labelMaker = "\'";
   labelMaker += WindowName;
   labelMaker += "\'/\'";
   labelMaker += labelIdsAboveMe[i];
   labelMaker += "\' group=\'";
   labelMaker += labelIdsAboveMe[i-1];
   labelMaker += "\'";
   TwDefine(labelMaker.c_str());

   //Rename Group
   labelMaker = "\'";
   labelMaker += WindowName;
   labelMaker += "\'/\'";
   labelMaker += labelIdsAboveMe[i];
   labelMaker += "\'  label=\'";
   labelMaker += labelNamesAboveMe[i];
   labelMaker += "\'";
   TwDefine(labelMaker.c_str());
  }
  labelNamesAboveMe.pop_back();
  labelIdsAboveMe.pop_back();
  return baby;
 }

 AntBarGroup::AntBarGroup(const std::string& WindowName_, const std::string& name, const std::vector labelIdsOboveMe, const std::vector labelNamesOboveMe, TwBar* mybar_ )
 {
  mybar = mybar_;
  WindowName = WindowName_;
  labelIdsAboveMe = labelIdsOboveMe;
  labelNamesAboveMe = labelNamesOboveMe;
  IdName = name;
  UnderHoodId = GetNextId();
  //Register Group
 }

 AntBarGroup* AntBarGroup::CreateGroup( const std::string& name )
 {
  GroupNameToId[name] = GroupIdToGroup.size();
  labelIdsAboveMe.push_back(UnderHoodId);
  labelNamesAboveMe.push_back(IdName);
  GroupIdToGroup[GroupIdToGroup.size()] = new AntBarGroup(WindowName, name, labelIdsAboveMe, labelNamesAboveMe, mybar);
  labelIdsAboveMe.pop_back();
  labelNamesAboveMe.pop_back();
  return GroupIdToGroup[GroupIdToGroup.size() - 1];
 }

 AntBarVariable* AntBarGroup::CreateROFloatVariable( const std::string& name, int data )
 {
  typeOfVariable* temp = CreateSettings();
  temp->Setting_RO = true;
  temp->Setting_FLOAT = true;
  temp->data = reinterpret_cast(data);
  return CreateVariable(name, temp);
 }

 typeOfVariable* AntBarGroup::CreateSettings()
 {
  return new typeOfVariable;
 }


 typeOfVariable::typeOfVariable()
 {
  Setting_RO = false; //Set if data is read only.
  Setting_RW = false;
  Setting_BUTTON = false;

  Setting_INT = false;
  Setting_FLOAT = false;
  Setting_BOOL = false;
  Setting_STD_STRING = false;
  Setting_QUAT4F = false;
  Setting_VEC3F = false;
  Setting_VEC2F = false;
  Settings_ENUMID = -1;
  data = 0;
 }

//Adds a variable to the current group
 AntBarVariable::AntBarVariable( TwBar* myBar, const std::string &RealName, typeOfVariable* Settings_, const std::string& BarName)
 {
  std::string Name = GetNextId();
  UnderHoodId = Name;
  Settings = Settings_;

  if((*Settings).Setting_RO && (*Settings).Getter.IsEmpty())
  {
   if((*Settings).Setting_INT)
   {
    TwAddVarRO(myBar, Name.c_str(), TW_TYPE_INT32, (*Settings).data, 0);
   }
   else if((*Settings).Setting_FLOAT)
   {
    TwAddVarRO(myBar, Name.c_str(), TW_TYPE_FLOAT, (*Settings).data, "precision=3");
   }
   else if((*Settings).Setting_BOOL)
   {
    TwAddVarRO(myBar, Name.c_str(), TW_TYPE_BOOLCPP, (*Settings).data, 0);
   }
   else if((*Settings).Setting_STD_STRING)
   {
    TwAddVarRO(myBar, Name.c_str(), TW_TYPE_STDSTRING, (*Settings).data, 0);
   }
   else if((*Settings).Setting_QUAT4F)
   {
    TwAddVarRO(myBar, Name.c_str(), TW_TYPE_QUAT4F, (*Settings).data, 0);
   }
   else if((*Settings).Setting_VEC3F)
   {
    TwAddVarRO(myBar, Name.c_str(), TW_TYPE_DIR3F, (*Settings).data, 0);
   }
   else if((*Settings).Setting_VEC2F)
   {
    TwAddVarRO(myBar, Name.c_str(), TW_TYPE_DIR3F, (*Settings).data, 0);
   }
  }
  else if((*Settings).Setting_RW && (*Settings).Getter.IsEmpty())
  {
   if((*Settings).Setting_INT)
   {
    TwAddVarRW(myBar, Name.c_str(), TW_TYPE_INT32, (*Settings).data, 0);
   }
   else if((*Settings).Setting_FLOAT)
   {
    TwAddVarRW(myBar, Name.c_str(), TW_TYPE_FLOAT, (*Settings).data, 0);
   }
   else if((*Settings).Setting_BOOL)
   {
    TwAddVarRW(myBar, Name.c_str(), TW_TYPE_BOOLCPP, (*Settings).data, 0);
   }
   else if((*Settings).Setting_STD_STRING)
   {
    TwAddVarRW(myBar, Name.c_str(), TW_TYPE_STDSTRING, (*Settings).data, 0);
   }
   else if((*Settings).Setting_QUAT4F)
   {
    TwAddVarRW(myBar, Name.c_str(), TW_TYPE_QUAT4F, (*Settings).data, 0);
   }
   else if((*Settings).Setting_VEC3F)
   {
    TwAddVarRW(myBar, Name.c_str(), TW_TYPE_DIR3F, (*Settings).data, 0);
   }
   else if((*Settings).Setting_VEC2F)
   {
    TwAddVarRW(myBar, Name.c_str(), TW_TYPE_DIR3F, (*Settings).data, 0);
   }
  }
  else if((*Settings).Setting_BUTTON)
  {
   TwAddButton(myBar, Name.c_str(), (*Settings).buttonCallback, (*Settings).data, 0);
  }
  else if(!(*Settings).ButtonPressed.IsEmpty())
  {
   TwAddButton(myBar, Name.c_str(), TWButtonCallback, Settings, 0);
  }
  else if(!(*Settings).Getter.IsEmpty())
  {
   TwSetVarCallback setter = TWBSetCallback;
   TwGetVarCallback getter = TWBGetCallback;
   if((*Settings).Setter.IsEmpty())
    setter = 0;
   if((*Settings).Setting_INT)
   {
    TwAddVarCB(myBar, Name.c_str(), TW_TYPE_INT32, setter, getter, Settings, 0);
   }
   else if((*Settings).Setting_FLOAT)
   {
    TwAddVarCB(myBar, Name.c_str(), TW_TYPE_FLOAT, setter, getter, Settings, 0);
   }
   else if((*Settings).Setting_BOOL)
   {
    TwAddVarCB(myBar, Name.c_str(), TW_TYPE_BOOLCPP, setter, getter, Settings, 0);
   }
   else if((*Settings).Setting_STD_STRING)
   {
    TwAddVarCB(myBar, Name.c_str(), TW_TYPE_STDSTRING, setter, getter, Settings, 0);
   }
   else if((*Settings).Setting_QUAT4F)
   {
    TwAddVarCB(myBar, Name.c_str(), TW_TYPE_QUAT4F, setter, getter, Settings, 0);
   }
   else if((*Settings).Setting_VEC3F)
   {
    TwAddVarCB(myBar, Name.c_str(), TW_TYPE_DIR3F, setter, getter, Settings, 0);
   }
   else if((*Settings).Setting_VEC2F)
   {
    TwAddVarCB(myBar, Name.c_str(), TW_TYPE_DIR3F, setter, getter, Settings, 0);
   }
  }

  if( (*Settings).Settings_ENUMID != -1)
  {
   AntBarEnumerationManager* emew = CoreHas(AntBar)->enumerations;
   emew->CreateVariableCB(myBar, Name.c_str(), Settings);
  }

  napkin = "\'";
  napkin += BarName;
  napkin += "\'/\'";
  napkin +=Name;
  napkin += "\'  label=\'";
  napkin +=RealName;
  napkin += "\'";
  if(!TwDefine(napkin.c_str()))
   ConsoleMessage("%s", TwGetLastError());
 }

 void TW_CALL TWBSetCallback(const void *value, void *clientData)
 {
  v8::HandleScope scope;
  typeOfVariable* Settings = (typeOfVariable*) clientData;
  ErrorIf(Settings->Setter.IsEmpty(), "YOU DIDN\'T GIVE ME A SETTER JERK");
  if(Settings->Setting_INT)
  {
   v8::Handle argv[] = {JavaScript::CastToJavaScript(*(int const*)value)};
   JavaScript::RunFunction(Settings->Setter, _countof(argv), argv);

  }
  else if(Settings->Settings_ENUMID != -1)
  {
   v8::Handle argv[] = {JS_AB::CastToJavaScript(Settings->Settings_ENUMID, *(int const*)value)};
   JavaScript::RunFunction(Settings->Setter, _countof(argv), argv);
  }
  else if(Settings->Setting_FLOAT)
  {
   v8::Handle argv[] = {JavaScript::CastToJavaScript(*(float const*)value)};
   JavaScript::RunFunction(Settings->Setter, _countof(argv), argv);
  }
  else if(Settings->Setting_BOOL)
  {
   v8::Handle argv[] = {JavaScript::CastToJavaScript(*(bool const*)value)};
   JavaScript::RunFunction(Settings->Setter, _countof(argv), argv);
  }
  else if(Settings->Setting_STD_STRING)
  {
   v8::Handle argv[] = {JavaScript::CastToJavaScript(*(std::string const*)value)};
   JavaScript::RunFunction(Settings->Setter, _countof(argv), argv);
  }
  else if((*Settings).Setting_QUAT4F)
  {
   float const *v = (float const*)value;
   v8::Handle argv[] = {JavaScript::CastToJavaScript(vec4(v[0], v[1], v[2], v[3]))};
   JavaScript::RunFunction(Settings->Setter, _countof(argv), argv);
  }
  else if((*Settings).Setting_VEC3F)
  {
   float const *v = (float const*)value;
   v8::Handle argv[] = {JavaScript::CastToJavaScript(vec3(v[0], v[1], v[2]))};
   JavaScript::RunFunction(Settings->Setter, _countof(argv), argv);
  }
  else if((*Settings).Setting_VEC2F)
  {
   float const *v = (float const*)value;
   v8::Handle argv[] = {JavaScript::CastToJavaScript(vec2(v[0], v[1]))};
   JavaScript::RunFunction(Settings->Setter, _countof(argv), argv);
  }
 }

 void TW_CALL TWBGetCallback(void *value, void *clientData)
 {
  v8::HandleScope scope;
  typeOfVariable* Settings = (typeOfVariable*) clientData;
  ErrorIf(Settings->Getter.IsEmpty(), "YOU DIDN\'T GIVE ME A SETTER JERK");
  if(Settings->Setting_INT)
  {
   v8::Local ret = JavaScript::RunFunction(Settings->Getter, 0, NULL);
   *(int*)value = ret->Int32Value();
  }
  else if(Settings->Settings_ENUMID != -1)
  {
   v8::Local ret = JavaScript::RunFunction(Settings->Getter, 0, NULL);
   JavaScriptType enum_value;
   JavaScript::CastFromJavaScript(ret, enum_value);
   *(int*)value = enum_value;
  }
  else if(Settings->Setting_FLOAT)
  {
   v8::Local ret = JavaScript::RunFunction(Settings->Getter, 0, NULL);
   JavaScript::CastFromJavaScript(ret, *(float*)value);
  }
  else if(Settings->Setting_BOOL)
  {
   v8::Local ret = JavaScript::RunFunction(Settings->Getter, 0, NULL);
   JavaScript::CastFromJavaScript(ret, *((bool*)value));
  }
  else if(Settings->Setting_STD_STRING)
  {
   v8::Local ret = JavaScript::RunFunction(Settings->Getter, 0, NULL);
   std::string ret_string;
   JavaScript::CastFromJavaScript(ret, ret_string);
   TwCopyStdStringToLibrary(*(std::string*)value, ret_string);
  }
  else if(Settings->Setting_QUAT4F)
  {
   v8::Local ret = JavaScript::RunFunction(Settings->Getter, 0, NULL);
   vec4 result; JavaScript::CastFromJavaScript(ret, result);
   ((float*)value)[0] = result.x;
   ((float*)value)[1] = result.y;
   ((float*)value)[2] = result.z;
   ((float*)value)[3] = result.w;
  }
  else if(Settings->Setting_VEC3F)
  {
   v8::Local ret = JavaScript::RunFunction(Settings->Getter, 0, NULL);
   vec3 result; JavaScript::CastFromJavaScript(ret, result);
   ((float*)value)[0] = result.x;
   ((float*)value)[1] = result.y;
   ((float*)value)[2] = result.z;
  }
  else if(Settings->Setting_VEC2F)
  {
   v8::Local ret = JavaScript::RunFunction(Settings->Getter, 0, NULL);
   vec2 result; JavaScript::CastFromJavaScript(ret, result);
   ((float*)value)[0] = result.x;
   ((float*)value)[1] = result.y;
   ((float*)value)[2] = 0;
  }
 }

 void TW_CALL TWButtonCallback( void *clientData )
 {
  v8::HandleScope scope;
  typeOfVariable* Settings = (typeOfVariable*) clientData;
  ErrorIf(Settings->ButtonPressed.IsEmpty(), "YOU DIDN\'T GIVE ME A CALL BACK JERK");
  JavaScript::RunFunction(Settings->ButtonPressed, 0, NULL);
 }

 AntBarEnumerationManager::~AntBarEnumerationManager()
 {
  for(;!intToTypes.empty(); intToTypes.erase(intToTypes.begin()))
   delete intToTypes.begin()->second;
 }
static int EnumId = 0;
 int AntBarEnumerationManager::CreateNewEnum(const std::string& typeName)
 {
  AntBarEnumeration* created = new AntBarEnumeration();
  created->IdName = typeName;
  stringToTypes[typeName] = created;
  int Id = EnumId++;
  intToTypes[Id] = created;
  return Id;
 }

 void AntBarEnumerationManager::AddEnum(int EnumId, const std::string& EnumName)
 {
  intToTypes[EnumId]->Enums.push_back(EnumName);
 }

 void AntBarEnumerationManager::DeleteEnum(int EnumId, const std::string& EnumName)
 {
  AntBarEnumeration* found = intToTypes[EnumId];
  ErrorIf(!found, "ENUMID %d is not valid!", EnumId);
  //Search for the enum
  for(std::vector::iterator iter = found->Enums.begin(); iter != found->Enums.end(); ++iter)
  {
   if(*iter == EnumName)
   {
    found->Enums.erase(iter);
    GetTwType(EnumId);
    return;
   }
  }
 }

 TwType AntBarEnumerationManager::GetTwType(int index)
 {
  bool sizeIsGood = true;
  AntBarEnumeration*found = intToTypes[index];
  if(!found->Enums.size())
  {
   sizeIsGood = false;
   found->Enums.push_back("null");
  }

  napkin = found->Enums[0];
  napkin += ",";
  for(unsigned i = 1; i < found->Enums.size(); ++i)
  {
   napkin += found->Enums[i];
   napkin += ",";
  }
  napkin.erase(napkin.end() - 1);

  if(!sizeIsGood)
   found->Enums.pop_back();

  return TwDefineEnumFromString(found->IdName.c_str(), napkin.c_str());
 }

 void AntBarEnumerationManager::CreateVariableCB(TwBar* bar, const std::string& name, typeOfVariable* Settings)
 {
   TwSetVarCallback setter = TWBSetCallback;
   TwGetVarCallback getter = TWBGetCallback;

   TwAddVarCB(bar, name.c_str(), GetTwType(Settings->Settings_ENUMID), setter, getter, Settings, NULL);
 }
 AntBarGroup::~AntBarGroup()
 {
  for(std::map::iterator iter = VarIdToVariable.begin(); iter != VarIdToVariable.end(); ++iter)
  {
   delete iter->second;
  }
  for(std::map::iterator iter = GroupIdToGroup.begin(); iter != GroupIdToGroup.end(); ++iter)
  {
   delete iter->second;
  }
 }
 AntBarVariable::~AntBarVariable()
 {
  if(Settings)
  {
   if(!Settings->Getter.IsEmpty()) { Settings->Getter.Dispose(); Settings->Getter.Clear(); }
   if(!Settings->Setter.IsEmpty()) { Settings->Setter.Dispose(); Settings->Setter.Clear(); }
   if(!Settings->ButtonPressed.IsEmpty()) { Settings->ButtonPressed.Dispose(); Settings->ButtonPressed.Clear(); }
   delete Settings;
  }
 }

 AntBarWindow::~AntBarWindow()
 {
  if(baseLabel)
   delete baseLabel;
  TwDeleteBar(mybar);
 }

 void AntBarWindow::Clear()
 {
  if(baseLabel)
   delete baseLabel;
  TwRemoveAllVars(mybar);

  baseLabel = new AntBarGroup(UnderHoodId, "", std::vector(), std::vector(), mybar);
  baseLabel->IdVal = 0;
 }

 void AntBar::Delete(AntBarWindow* window)
 {
  //Find in window pointers
  for(std::map::iterator iter = IdToObject.begin(); iter != IdToObject.end(); ++iter)
  {
   if(iter->second == window)
   {
    delete window;
    IdToObject.erase(iter);
    return;
   }
  }
 }

 void AntBar::ToggleDraw( void )
 {
  this->DrawAntBar = !DrawAntBar;
 }

}//Framework



You can also view and download both the header and the source.