#include "MW4Headers.hpp" #include "AI_Log.hpp" #include "aiutils.hpp" #include "MWPlayer.hpp" #include "VehicleInterface.hpp" int g_objects_in_existence = 0; using namespace MW4AI; LogNode::LogNode(Type type, const std::string& text, const std::string& label) : m_Text(text) , m_Type(type) , m_Label(label) , m_Line(0) { Verify(type >= TYPE_FIRST); Verify(type <= TYPE_LAST); ++g_objects_in_existence; } LogNode::LogNode(Type type, const std::string& text, const std::string& label, const std::string& filename, int line_number) : m_Text(text) , m_Type(type) , m_Label(label) , m_File(filename) , m_Line(line_number) { Verify(type >= TYPE_FIRST); Verify(type <= TYPE_LAST); ++g_objects_in_existence; } LogNode::~LogNode() { --g_objects_in_existence; while (m_Children.size() > 0) { delete (*(m_Children.begin())); m_Children.erase(m_Children.begin()); } } LogNode* LogNode::AddChild(Type type, const std::string& text, const std::string& label) { LogNode* new_node = new LogNode(type,text,label); m_Children.push_back(new_node); return (new_node); } LogNode* LogNode::AddChild(Type type, const std::string& text, const std::string& label, const std::string& filename, int line_number) { LogNode* new_node = new LogNode(type,text,label,filename,line_number); m_Children.push_back(new_node); return (new_node); } LogNode* LogNode::Find(const std::string& text) { {for (std::vector::iterator i = m_Children.begin(); i != m_Children.end(); ++i) { LogNode* found = (*i)->Find(text); if (found != 0) { return (found); } }} if (m_Text == text) { return (this); } return (0); } std::string LogNode::GetText() const { return (m_Text); } LogNode::Type LogNode::GetType() const { return (m_Type); } std::string LogNode::GetLabel() const { return (m_Label); } std::string LogNode::GetFile() const { return (m_File); } int LogNode::GetLine() const { return (m_Line); } void LogNode::SpewToString(std::string& output, unsigned int level, bool first_in_row) const { std::string prefix; if (m_Text.size() > 0) { {for (unsigned int i = 0; i < level; ++i) { prefix += " | "; }} if (GetType() == LogNode::TYPE_FUNCTION) { output += prefix; } output += m_Text; if (m_Label.size() != 0) { output += " ("; output += m_Label; output += ")"; } if (m_File.size() != 0) { std::string f = m_File; while (f.find('\\') != std::string::npos) { f.erase(0,1); } output += " ["; output += f; output += ", line "; output += IntToString(m_Line); output += "]"; } if (GetType() == LogNode::TYPE_FUNCTION) { output += "\n"; } } bool fDrawn = false; {for (std::vector::const_iterator i = m_Children.begin(); i != m_Children.end(); ++i) { if ((*i)->GetType() == LogNode::TYPE_PARAMETER) { if (fDrawn == false) { output += prefix; } else { output += ", "; } (*i)->SpewToString(output,level+1); fDrawn = true; } }} {for (std::vector::const_iterator i = m_Children.begin(); i != m_Children.end(); ++i) { if ((*i)->GetType() == LogNode::TYPE_RETURN_VALUE) { if (fDrawn == false) { output += prefix; } else { output += ", "; } (*i)->SpewToString(output,level+1); fDrawn = true; } }} if (fDrawn == true) { output += "\n"; } {for (std::vector::const_iterator i = m_Children.begin(); i != m_Children.end(); ++i) { if ((*i)->GetType() == LogNode::TYPE_FUNCTION) { (*i)->SpewToString(output,level+1); } }} } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // DiagnosticsInterface* DiagnosticsInterface::m_Instance = 0; DiagnosticsInterface::DiagnosticsInterface() : m_Enabled(false) , m_ExecutingObject(0) , m_FileAndLineEnabled(false) , m_ParameterNamesEnabled(false) , m_FileSpewing(false) { Verify(m_Instance == 0); m_Instance = this; m_Root.Assimilate(new LogNode(LogNode::TYPE_FUNCTION,"")); } DiagnosticsInterface::~DiagnosticsInterface() { Verify(m_Instance == this); m_Instance = 0; } void DiagnosticsInterface::Reset() { if (m_Root.GetPointer() != 0) { m_Root.Delete(); m_Root.Assimilate(new LogNode(LogNode::TYPE_FUNCTION,"")); } } DiagnosticsInterface& DiagnosticsInterface::GetInstance() { Verify(m_Instance != 0); return (*m_Instance); } void DiagnosticsInterface::Log(LogNode::Type type, const std::string& value, const std::string& label) { if (CanLog() == false) { return; } std::string l; if ((GetParameterNamesEnabled() == true) || (type != LogNode::TYPE_PARAMETER)) { l = label; } Verify(m_Stack.size() > 0); m_Stack.back()->AddChild(type,value,l); } void DiagnosticsInterface::Log(LogNode::Type type, const Stuff::Scalar& value, const std::string& label) { if (CanLog() == false) { return; } Log(type,ScalarToString(value),label); } void DiagnosticsInterface::Log(LogNode::Type type, const Stuff::Point3D& value, const std::string& label) { if (CanLog() == false) { return; } std::string s("("); s += ScalarToString(value.x); s += ","; s += ScalarToString(value.y); s += ","; s += ScalarToString(value.z); s += ")"; Log(type,s,label); } void DiagnosticsInterface::Log(LogNode::Type type, const int& value, const std::string& label) { if (CanLog() == false) { return; } Log(type,IntToString(value),label); } void DiagnosticsInterface::Log(LogNode::Type type, const bool& value, const std::string& label) { if (CanLog() == false) { return; } Log(type,BoolToString(value),label); } void DiagnosticsInterface::Log(LogNode::Type type, const TacticInterface::WR_WHO& value, const std::string& label) { if (CanLog() == false) { return; } switch (value) { case TacticInterface::SELF: { Log(type,(std::string)"Self",label); return; } case TacticInterface::TARGET: { Log(type,(std::string)"Target",label); return; } } Log(type,(std::string)"***INVALID***",label); } void DiagnosticsInterface::Log(LogNode::Type type, const TacticInterface::WR_QUALIFIER& value, const std::string& label) { if (CanLog() == false) { return; } switch (value) { case TacticInterface::MIN: { Log(type,(std::string)"Min",label); return; } case TacticInterface::MAX: { Log(type,(std::string)"Max",label); return; } } Log(type,(std::string)"***INVALID***",label); } void DiagnosticsInterface::Log(LogNode::Type type, const Stuff::Time& value, const std::string& label) { if (CanLog() == false) { return; } Log(type,ScalarToString((Stuff::Scalar)value),label); } void DiagnosticsInterface::Log(LogNode::Type type, const UserConstants::ID& value, const std::string& label) { if (CanLog() == false) { return; } Log(type,IntToString((int)value),label); } void DiagnosticsInterface::Log(LogNode::Type type, const FireStyles::FireStyleID& value, const std::string& label) { if (CanLog() == false) { return; } Log(type,FireStyles::FireStyleToString(value),label); } void DiagnosticsInterface::Log(LogNode::Type type, const FireData::HIT_RESULT& value, const std::string& label) { if (CanLog() == false) { return; } switch (value) { case FireData::HIT_TARGET: { Log(type,(std::string)"HIT_TARGET",label); return; } case FireData::HIT_SOMETHING_ELSE: { Log(type,(std::string)"HIT_SOMETHING_ELSE",label); return; } case FireData::HIT_NOTHING: { Log(type,(std::string)"HIT_NOTHING",label); return; } } Log(type,(std::string)"***INVALID***",label); } void DiagnosticsInterface::PushFunction(const std::string& funcname, const std::string& file, int line) { if (CanLog() == false) { return; } LogNode* new_node = 0; if (m_Stack.size() == 0) { if (GetFileAndLineEnabled() == true) { new_node = m_Root->AddChild(LogNode::TYPE_FUNCTION,funcname,"",file,line); } else { new_node = m_Root->AddChild(LogNode::TYPE_FUNCTION,funcname); } } else { if (GetFileAndLineEnabled() == true) { new_node = m_Stack.back()->AddChild(LogNode::TYPE_FUNCTION,funcname,"",file,line); } else { new_node = m_Stack.back()->AddChild(LogNode::TYPE_FUNCTION,funcname); } } m_Stack.push_back(new_node); } void DiagnosticsInterface::PopFunction(const std::string& funcname) { if (CanLog() == false) { return; } Verify(m_Stack.size() > 0); Verify(m_Stack.back()->GetText() == funcname); m_Stack.pop_back(); if (m_Stack.size() == 0) { if (m_Root.GetPointer() != 0) { m_BufferedSpew = ""; m_Root->SpewToString(m_BufferedSpew); } } } void DiagnosticsInterface::SetEnabled(bool enabled) { #ifdef LAB_ONLY m_Enabled = enabled; #endif } bool DiagnosticsInterface::GetEnabled() const { return (m_Enabled); } void DiagnosticsInterface::SetFileAndLineEnabled(bool enabled) { m_FileAndLineEnabled = enabled; } bool DiagnosticsInterface::GetFileAndLineEnabled() const { return (m_FileAndLineEnabled); } void DiagnosticsInterface::SetParameterNamesEnabled(bool enabled) { m_ParameterNamesEnabled = enabled; } bool DiagnosticsInterface::GetParameterNamesEnabled() const { return (m_ParameterNamesEnabled); } void DiagnosticsInterface::SetFileSpewing(bool enabled) { m_FileSpewing = enabled; } bool DiagnosticsInterface::GetFileSpewing() const { return (m_FileSpewing); } void DiagnosticsInterface::GetSpew(std::string& output) const { output = m_BufferedSpew; } Adept::Entity* GetPlayerVehicle() { if (Adept::Player::GetInstance() == 0) { return (0); } MechWarrior4::MWPlayer* p = Cast_Object(MechWarrior4::MWPlayer*,Adept::Player::GetInstance()); if (p == 0) { return (0); } Check_Object(p); if (p->GetInterface() == 0) { return (0); } return (p->GetInterface()->vehicle); } void DiagnosticsInterface::SetExecutingObject(MechWarrior4::MWObject* object) { m_ExecutingObject = object; if ((m_ExecutingObject != 0) && (GetPlayerVehicle() != 0) && (m_ExecutingObject == GetPlayerVehicle())) { Reset(); } } bool DiagnosticsInterface::CanLog() const { if ((GetEnabled() == false) || (m_ExecutingObject == 0) || (GetPlayerVehicle() == 0)) { return (false); } return (m_ExecutingObject == GetPlayerVehicle()); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LogFunction::LogFunction(const std::string& name, const std::string& file, int line) : m_Name(name) { DiagnosticsInterface::GetInstance().PushFunction(m_Name,file,line); } LogFunction::~LogFunction() { DiagnosticsInterface::GetInstance().PopFunction(m_Name); }