Browse Source

Replaced PLog, added file_regex

- Removed PLog as a dependency. Unreal requires me to use its custom allocator, which std::string doesn't really work with. I wrote a logger with an interface similar to PLog's that only uses C strings
- AgentGoalDefs are in a dictionary now
- Sublime can now detect compilation errors. This is mostly for my own convenience
combatComponentRefactor
Macoy Madson 6 years ago
parent
commit
b417270895
  1. 4
      .gitignore
  2. 3
      .gitmodules
  3. 3
      README.md
  4. 18
      TODO.txt
  5. 21
      src/ai/htn/HTNTasks.cpp
  6. 7
      src/ai/htn/HTNTasks.hpp
  7. 5
      src/game/agent/AgentComponentManager.cpp
  8. 18
      src/project/galavantSublime/galavant.sublime-project
  9. 10
      src/unitTesting/HTN_test.cpp
  10. 6
      src/unitTesting/Jamfile
  11. 64
      src/unitTesting/Log_test.cpp
  12. 2
      src/unitTesting/StringHashing_test.cpp
  13. 117
      src/util/Logging.cpp
  14. 175
      src/util/Logging.hpp
  15. 2
      src/util/StringHashing.hpp
  16. 9
      src/world/Position.cpp
  17. 9
      src/world/Position.hpp
  18. 1
      thirdParty/plog

4
.gitignore

@ -52,4 +52,6 @@ LOCAL*
CppCheckResults.xml
ValgrindOut.xml
*.ycm_extra_conf.py
*.ycm_extra_conf.py
*.blend1

3
.gitmodules

@ -4,6 +4,3 @@
[submodule "thirdParty/Catch"]
path = thirdParty/Catch
url = https://github.com/philsquared/Catch.git
[submodule "thirdParty/plog"]
path = thirdParty/plog
url = https://github.com/SergiusTheBest/plog

3
README.md

@ -33,9 +33,6 @@ The following libraries are required by Galavant and included in /thirdParty:
- [OpenSimplexNoise](https://gist.github.com/tombsar/716134ec71d1b8c1b530), created by Arthur Tombs (public domain)
- [Flatbuffers](https://github.com/google/flatbuffers), created by Google/Fun Propulsion Labs (Apache License, v2.0)
- [Catch](https://github.com/philsquared/Catch), created by various contributors/a dude named Travis (Boost Software License)
- [PLog](https://github.com/SergiusTheBest/plog), created by Sergey Podobry (Mozilla Public License v2.0)
Unfortunately, some third party library files needed modification in order to be included. These modifications are kept in src/thirdPartyModifiedFiles. You'll have to diff the modified files with the repository files and copy over my changes.
## License

18
TODO.txt

@ -12,11 +12,11 @@ What does agent component manager do with triggers once plan is done? How to kno
Pickups sort of working, sometimes they aren't picked up, Actors are being destroyed strangely
Possibility that pickup actor is falling through the floor (invisible other component hitting KillZ?) YES, it's KillZ
HUD Minimap is difficult to use with regards to rotation (needs better view cone)
Minimap noise doesn't match world
Scaling is completely wrong between WorldResource position and noise sample
Actually, this doesn't seem to be the problem
Minimap
HUD Minimap is difficult to use with regards to rotation (needs better view cone)
Minimap noise doesn't match world
Scaling is completely wrong between WorldResource position and noise sample
Actually, this doesn't seem to be the problem
Some sort of resource system
Could be something like ResourceDictionary<key, ResourceType> resources
@ -24,21 +24,25 @@ Some sort of resource system
Put HTN Tasks etc. in resource dictionaries? Who owns them?
Sublime "syntax" tag for build systems
----------------------------------------------------------------------------------------------------
DOING
----------------------------------------------------------------------------------------------------
Logging broke as shit
https://answers.unrealengine.com/questions/435366/linux-crash-in-stdstring-destructor.html ?
Test PlanComponent event stuff
It seems to have broken things
----------------------------------------------------------------------------------------------------
DONE
----------------------------------------------------------------------------------------------------
Logging broke as shit
https://answers.unrealengine.com/questions/435366/linux-crash-in-stdstring-destructor.html ?
Chunks are fucked
HUD Minimap rotation indicator doesn't work right when pitching the camera

21
src/ai/htn/HTNTasks.cpp

@ -144,4 +144,25 @@ void PrintTaskCallList(const TaskCallList& tasks)
for (unsigned int i = 0; i < tasks.size(); i++)
LOGD << " [" << i << "] " << *tasks[i].TaskToCall;
}
}
template <>
gv::Logging::Record& gv::Logging::Record::operator<<<Htn::Task>(const Htn::Task& task)
{
switch (task.GetType())
{
case Htn::TaskType::None:
*this << "Task Type:None " << &task;
break;
case Htn::TaskType::Goal:
*this << "Task Type:Goal task addr " << &task << " Goal"; // << task.Goal;
break;
case Htn::TaskType::Compound:
*this << "Task Type:Compound addr " << &task << " Compound"; // << task.Compound;
break;
case Htn::TaskType::Primitive:
*this << "Task Type:Primitive addr " << &task << " Primitive"; // << task.Primitive;
break;
}
return *this;
}

7
src/ai/htn/HTNTasks.hpp

@ -41,7 +41,7 @@ struct Task
friend std::ostream& operator<<(std::ostream& os, const Task& task);
private:
protected:
union
{
GoalTask* Goal;
@ -140,4 +140,7 @@ std::ostream& operator<<(std::ostream& os, const Task& task);
void PrintTaskList(const TaskList& tasks);
void PrintTaskCallList(const TaskCallList& tasks);
}
}
template <>
gv::Logging::Record& gv::Logging::Record::operator<<<Htn::Task>(const Htn::Task& task);

5
src/game/agent/AgentComponentManager.cpp

@ -9,6 +9,8 @@
namespace gv
{
ResourceDictionary<AgentGoalDef> g_AgentGoalDefDictionary;
AgentComponentManager::AgentComponentManager() : gv::PooledComponentManager<AgentComponentData>(100)
{
Type = gv::ComponentType::Agent;
@ -45,7 +47,6 @@ void AgentComponentManager::Update(float deltaSeconds)
EntityList entitiesToUnsubscribe;
EntityList entitiesToDestroy;
PlanComponentManager::PlanComponentList newPlans;
const PlanExecutionEventList& planExecutionEvents = PlanManager->GetExecutionEvents();
if (!PlanManager)
{
@ -53,6 +54,8 @@ void AgentComponentManager::Update(float deltaSeconds)
return;
}
const PlanExecutionEventList& planExecutionEvents = PlanManager->GetExecutionEvents();
WorldTime += deltaSeconds;
// TODO: Adding true iterator support to pool will drastically help damning this to hell

18
src/project/galavantSublime/galavant.sublime-project

@ -61,14 +61,16 @@
{
"name": "Full Unreal Build (build Galavant lib and Unreal)",
"shell_cmd": "cd galavant && jam -j4 -q -sUNREAL=true GalavantPseudotarget && cd ../galavant-unreal/GalavantUnreal && make GalavantUnreal",
"working_dir": "$project_path/../../../.."
"working_dir": "$project_path/../../../..",
"file_regex": "^([a-zA-Z\/][^:\n]*):([0-9]+):?([0-9]+)?:? (.*)$",
},
// Unreal
{
"name": "Unreal Build",
"shell_cmd": "make GalavantUnreal",
"working_dir": "$project_path/../../../../galavant-unreal/GalavantUnreal"
"working_dir": "$project_path/../../../../galavant-unreal/GalavantUnreal",
"file_regex": "^([a-zA-Z\/][^:\n]*):([0-9]+):?([0-9]+)?:? (.*)$",
},
{
@ -86,22 +88,26 @@
// Jam
{
"name": "Jam Current Directory",
"shell_cmd": "jam -j4 -q"
"shell_cmd": "jam -j4 -q",
"file_regex": "^([a-zA-Z\/][^:\n]*):([0-9]+):?([0-9]+)?:? (.*)$",
},
{
"name": "Jam Clean All",
"shell_cmd": "jam clean",
"working_dir": "$project_path/../../.."
"working_dir": "$project_path/../../..",
"file_regex": "^([a-zA-Z\/][^:\n]*):([0-9]+):?([0-9]+)?:? (.*)$",
},
{
"name": "Jam Build (not Unreal)",
"shell_cmd": "jam -j4 -q",
"working_dir": "$project_path/../../.."
"working_dir": "$project_path/../../..",
"file_regex": "^([a-zA-Z\/][^:\n]*):([0-9]+):?([0-9]+)?:? (.*)$",
},
{
"name": "Jam Build Unreal",
"shell_cmd": "jam -j4 -q -sUNREAL=true GalavantPseudotarget",
"working_dir": "$project_path/../../.."
"working_dir": "$project_path/../../..",
"file_regex": "^([a-zA-Z\/][^:\n]*):([0-9]+):?([0-9]+)?:? (.*)$",
},
// Misc. C++ Commands

10
src/unitTesting/HTN_test.cpp

@ -3,11 +3,13 @@
#define CATCH_CONFIG_MAIN
#include "../../thirdParty/Catch/single_include/catch.hpp"
#include "../util/Logging.hpp"
#include "util/Logging.hpp"
#include "../ai/htn/HTNTypes.hpp"
#include "../ai/htn/HTNTasks.hpp"
#include "../ai/htn/HTNPlanner.hpp"
#include "ai/htn/HTNTypes.hpp"
#include "ai/htn/HTNTasks.hpp"
#include "ai/htn/HTNPlanner.hpp"
static gv::Logging::Logger s_logger;
class AlwaysFailPrimitiveTask : public Htn::PrimitiveTask
{

6
src/unitTesting/Jamfile

@ -3,7 +3,7 @@ SubDir . src unitTesting ;
SubDirC++Flags $(TESTSC++FLAGS) ;
Main entityComponentTest : EntityComponentSystem_test.cpp ;
LinkLibraries entityComponentTest : libGalaEntityComponent ;
LinkLibraries entityComponentTest : libGalaEntityComponent libGalaUtil ;
Main objectPoolTest : ObjectPoolTest.cpp ;
@ -11,11 +11,13 @@ Main htnTest : HTN_test.cpp ;
LinkLibraries htnTest : libGalaAi libGalaUtil ;
Main positionTest : Position_test.cpp ;
LinkLibraries positionTest : libGalaWorld ;
LinkLibraries positionTest : libGalaWorld libGalaUtil ;
Main logTest : Log_test.cpp ;
LinkLibraries logTest : libGalaUtil ;
Main stringHashTest : StringHashing_test.cpp ;
LinkLibraries stringHashTest : libGalaUtil ;
MakeLocate objectComponentTest
entityComponentTest

64
src/unitTesting/Log_test.cpp

@ -3,74 +3,28 @@
#define CATCH_CONFIG_MAIN
#include "../../thirdParty/Catch/single_include/catch.hpp"
#include <plog/Log.h>
#include <plog/Formatters/FuncMessageFormatter.h>
#include <plog/Appenders/ColorConsoleAppender.h>
#include "util/Logging.hpp"
#include <list>
static gv::Logging::Logger s_logger;
#include "../util/Logging.hpp"
// Copied from thirdParty/plog/samples/CustomAppender/Main.cpp
namespace plog
{
template <class Formatter>
class MyAppender : public IAppender
void testFuncName()
{
public:
virtual void write(const Record& record)
{
util::nstring str = Formatter::format(record);
m_messageList.push_back(str);
}
std::list<util::nstring>& getMessageList()
{
return m_messageList;
}
private:
std::list<util::nstring> m_messageList;
};
LOGD << "The funcName should be formatted correctly here";
}
TEST_CASE("Log")
{
SECTION("Log Writing to file")
{
const char* logName = "LOCAL_TestLog.log";
plog::init(plog::debug, logName);
LOG_DEBUG << "Test log";
// To confirm the log worked, check if the file exists
// http://stackoverflow.com/questions/12774207/fastest-way-to-check-if-a-file-exist-using-standard-c-c11-c
struct stat buffer;
REQUIRE(stat(logName, &buffer) == 0);
}
SECTION("Log Custom Appender")
{
static plog::MyAppender<plog::FuncMessageFormatter> myAppender;
plog::init(plog::debug, &myAppender);
LOGD << "A debug message!";
REQUIRE(!myAppender.getMessageList().empty());
}
SECTION("Log Console Appender")
{
static plog::ColorConsoleAppender<plog::FuncMessageFormatter> s_ConsoleLogAppender;
plog::init(plog::debug, &s_ConsoleLogAppender);
for (int i = 0; i < 10; i++)
LOGD << "[" << i << "]";
LOGD << "You should see 1 - 9 above";
LOGD << "Does this print once? Because it should";
testFuncName();
// I don't know how to test this
// I don't know how to test this
std::cout << "You should see 1 - 9 above. If you don't, the test actually failed!\n";
REQUIRE(true);
}
}

2
src/unitTesting/StringHashing_test.cpp

@ -1,5 +1,3 @@
#pragma once
#include <iostream>
#define CATCH_CONFIG_MAIN

117
src/util/Logging.cpp

@ -1,30 +1,121 @@
#include "Logging.hpp"
#include <plog/Formatters/FuncMessageFormatter.h>
#include <plog/Appenders/ColorConsoleAppender.h>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <iostream>
namespace gv
{
static bool gs_LoggingInitialized = false;
namespace Logging
{
Record::Record(Severity newSeverity, const char* func, size_t line, const char* file)
: severity(newSeverity), Function(func), Line(line), File(file), Offset(0)
{
}
Record& Record::operator<<(char data)
{
Offset += snprintf(OutBuffer + Offset, sizeof(OutBuffer) - Offset, "%d", (int)data);
return *this;
}
Record& Record::operator<<(const char* data)
{
Offset += snprintf(OutBuffer + Offset, sizeof(OutBuffer) - Offset, "%s", data);
return *this;
}
Record& Record::operator<<(const int data)
{
Offset += snprintf(OutBuffer + Offset, sizeof(OutBuffer) - Offset, "%d", data);
return *this;
}
Record& Record::operator<<(const unsigned int data)
{
Offset += snprintf(OutBuffer + Offset, sizeof(OutBuffer) - Offset, "%u", data);
return *this;
}
Record& Record::operator<<(const float data)
{
Offset += snprintf(OutBuffer + Offset, sizeof(OutBuffer) - Offset, "%f", data);
return *this;
}
Record& Record::operator<<(const bool data)
{
Offset +=
snprintf(OutBuffer + Offset, sizeof(OutBuffer) - Offset, "%s", data ? "True" : "False");
return *this;
}
Record& Record::operator<<(const size_t data)
{
Offset += snprintf(OutBuffer + Offset, sizeof(OutBuffer) - Offset, "%lu", (unsigned long)data);
return *this;
}
void InitializeConsoleOnlyLogging()
void FormatFuncName(char* buffer, const char* func, size_t bufferSize)
{
static plog::ColorConsoleAppender<plog::FuncMessageFormatter> s_ConsoleLogAppender;
const char* funcBegin = func;
const char* funcEnd = strchr(funcBegin, '(');
if (!gs_LoggingInitialized)
if (!funcEnd)
{
plog::init(plog::debug, &s_ConsoleLogAppender);
gs_LoggingInitialized = true;
strncpy(buffer, func, bufferSize - 1);
return;
}
for (const char* i = funcEnd - 1; i >= funcBegin;
--i) // search backwards for the first space char
{
if (*i == ' ')
{
funcBegin = i + 1;
break;
}
}
unsigned long numCharsToCopy = std::min((funcEnd - funcBegin), (long)bufferSize - 1);
strncpy(buffer, funcBegin, numCharsToCopy);
buffer[numCharsToCopy] = '\0';
}
// Feel free to pass in NULL to get the default log file
void InitializeFileOnlyLogging(const char* filename)
Logger::Logger(Severity maxSeverity, CustomLogOutputFunc customOutputFunc)
: MaxSeverity(maxSeverity), CustomOutputFunc(customOutputFunc)
{
if (!gs_LoggingInitialized)
Singleton = this;
std::cout << "Logger initialized at " << Singleton << "\n";
}
bool Logger::checkSeverity(Severity severity) const
{
return severity <= MaxSeverity;
}
void Logger::operator+=(const Record& record)
{
if (CustomOutputFunc)
CustomOutputFunc(record);
else
{
plog::init(plog::debug, filename ? filename : "LOCAL_Galavant.log");
gs_LoggingInitialized = true;
static char funcNameBuffer[256];
FormatFuncName(funcNameBuffer, record.Function, sizeof(funcNameBuffer));
std::cout << severityToString(record.severity) << " " << record.File << ":"
<< funcNameBuffer << "():" << record.Line << ": " << record.OutBuffer << "\n";
}
}
Logger* Logger::GetSingleton()
{
if (!Singleton)
std::cout << "Warning: something tried to access Logger before any Logger had been "
"initialized!\n";
return Singleton;
}
Logger* Logger::Singleton = nullptr;
}
}

175
src/util/Logging.hpp

@ -1,7 +1,82 @@
#pragma once
// Including Plog here for convenience and abstraction; that way users can just include Logging.hpp
#include <plog/Log.h>
// size_t
#include <stddef.h>
// This file is based on PLog's interface but uses C strings only. See Plog:
// Plog - portable and simple log for C++
// Documentation and sources: https://github.com/SergiusTheBest/plog
// License: MPL 2.0, http://mozilla.org/MPL/2.0/
// I had to cut PLog out because Unreal doesn't allow the use of std::string in any code
//////////////////////////////////////////////////////////////////////////
// Helper macros that get context info
/*#ifdef _MSC_VER
# define LOGGER_GET_FUNC() __FUNCTION__
#elif defined(__BORLANDC__)
# define LOGGER_GET_FUNC() __FUNC__
#else
# define LOGGER_GET_FUNC() __PRETTY_FUNCTION__
#endif*/
#define LOGGER_GET_FUNC() __PRETTY_FUNCTION__
/*#if gv::Logger_CAPTURE_FILE
# define LOGGER_GET_FILE() __FILE__
#else
# define LOGGER_GET_FILE() ""
#endif*/
#define LOGGER_GET_FILE() __FILE__
//////////////////////////////////////////////////////////////////////////
// Log severity level checker
#define IF_LOG_(severity) \
!(gv::Logging::Logger::GetSingleton() && \
gv::Logging::Logger::GetSingleton()->checkSeverity(severity)) ? \
(void)0:
#define IF_LOG(severity) IF_LOG_(severity)
//////////////////////////////////////////////////////////////////////////
// Main logging macros
#define LOG_(severity) \
IF_LOG_(severity) (*gv::Logging::Logger::GetSingleton()) += gv::Logging::Record(severity, LOGGER_GET_FUNC(), __LINE__, LOGGER_GET_FILE())
#define LOG(severity) LOG_(severity)
#define LOG_VERBOSE LOG(gv::Logging::Severity::verbose)
#define LOG_DEBUG LOG(gv::Logging::Severity::debug)
#define LOG_INFO LOG(gv::Logging::Severity::info)
#define LOG_WARNING LOG(gv::Logging::Severity::warning)
#define LOG_ERROR LOG(gv::Logging::Severity::error)
#define LOG_FATAL LOG(gv::Logging::Severity::fatal)
#define LOGV LOG_VERBOSE
#define LOGD LOG_DEBUG
#define LOGI LOG_INFO
#define LOGW LOG_WARNING
#define LOGE LOG_ERROR
#define LOGF LOG_FATAL
//////////////////////////////////////////////////////////////////////////
// Conditional logging macros
#define LOG_IF_(severity, condition) !(condition) ? void(0) : LOG_(severity)
#define LOG_IF(severity, condition) LOG_IF_(severity, condition)
#define LOG_VERBOSE_IF(condition) LOG_IF(gv::Logging::Severity::verbose, condition)
#define LOG_DEBUG_IF(condition) LOG_IF(gv::Logging::Severity::debug, condition)
#define LOG_INFO_IF(condition) LOG_IF(gv::Logging::Severity::info, condition)
#define LOG_WARNING_IF(condition) LOG_IF(gv::Logging::Severity::warning, condition)
#define LOG_ERROR_IF(condition) LOG_IF(gv::Logging::Severity::error, condition)
#define LOG_FATAL_IF(condition) LOG_IF(gv::Logging::Severity::fatal, condition)
#define LOGV_IF(condition) LOG_VERBOSE_IF(condition)
#define LOGD_IF(condition) LOG_DEBUG_IF(condition)
#define LOGI_IF(condition) LOG_INFO_IF(condition)
#define LOGW_IF(condition) LOG_WARNING_IF(condition)
#define LOGE_IF(condition) LOG_ERROR_IF(condition)
#define LOGF_IF(condition) LOG_FATAL_IF(condition)
namespace gv
{
@ -9,4 +84,100 @@ void InitializeConsoleOnlyLogging();
// Feel free to pass in NULL to get the default log file
void InitializeFileOnlyLogging(const char* filename);
namespace Logging
{
enum class Severity
{
none = 0,
fatal,
error,
warning,
info,
debug,
verbose
};
inline const char* severityToString(Severity severity)
{
switch (severity)
{
case Severity::fatal:
return "FATAL";
case Severity::error:
return "ERROR";
case Severity::warning:
return "WARN";
case Severity::info:
return "INFO";
case Severity::debug:
return "DEBUG";
case Severity::verbose:
return "VERB";
default:
return "NONE";
}
}
inline Severity severityFromString(const char* str)
{
for (Severity severity = Severity::fatal; severity <= Severity::verbose;
severity = static_cast<Severity>((int)severity + 1))
{
if (severityToString(severity)[0] == str[0])
{
return severity;
}
}
return Severity::none;
}
struct Record
{
Severity severity;
const char* const Function;
size_t Line;
const char* const File;
#define OUT_BUFFER_SIZE 1024
char OutBuffer[OUT_BUFFER_SIZE];
size_t Offset;
Record(Severity newSeverity, const char* func, size_t line, const char* file);
Record& operator<<(char data);
Record& operator<<(const char* data);
Record& operator<<(const int data);
Record& operator<<(const unsigned int data);
Record& operator<<(const float data);
Record& operator<<(const bool data);
Record& operator<<(const size_t data);
template <class T>
Record& operator<<(const T& data)
{
return *this;
}
};
using CustomLogOutputFunc = void (*)(const Record&);
void FormatFuncName(char* buffer, const char* func, size_t bufferSize);
class Logger
{
private:
Severity MaxSeverity;
static Logger* Singleton;
CustomLogOutputFunc CustomOutputFunc;
public:
Logger(Severity maxSeverity = Severity::verbose,
CustomLogOutputFunc customOutputFunc = nullptr);
bool checkSeverity(Severity severity) const;
void operator+=(const Record& record);
static Logger* GetSingleton();
};
}
}

2
src/util/StringHashing.hpp

@ -58,7 +58,7 @@ struct ConstCrc<size, size>
}
};
// This don't take into account the nul char
// This doesn't take into account the nul char
#define COMPILE_TIME_CRC32_STR(x) (ConstCrc<sizeof(x) - 1>::crc32(x))
// Runtime string hashing

9
src/world/Position.cpp

@ -134,10 +134,9 @@ GlobalPosition::GlobalPosition(Position& localPosition) : LocalPosition(localPos
}
}
namespace plog
template <>
gv::Logging::Record& gv::Logging::Record::operator<<<gv::Position>(const gv::Position& data)
{
Record& operator<<(Record& record, const gv::Position& position)
{
return record << "(" << position.X << ", " << position.Y << ", " << position.Z << ")";
}
*this << "(" << data.X << ", " << data.Y << ", " << data.Z << ")";
return *this;
}

9
src/world/Position.hpp

@ -2,7 +2,7 @@
#include <vector>
#include "../util/Logging.hpp"
#include "util/Logging.hpp"
namespace gv
{
@ -45,6 +45,7 @@ struct Position
bool operator==(const Position& otherPosition) const;
};
// TODO: Chunk/global position
struct GlobalPosition
{
Position LocalPosition;
@ -59,7 +60,5 @@ typedef std::vector<Position> PositionList;
typedef std::vector<Position*> PositionRefList;
};
namespace plog
{
Record& operator<<(Record& record, const gv::Position& position);
}
template <>
gv::Logging::Record& gv::Logging::Record::operator<<<gv::Position>(const gv::Position& data);

1
thirdParty/plog

@ -1 +0,0 @@
Subproject commit b50e70ec46eff7946b84c8ea961b0fd25c3819d8
Loading…
Cancel
Save