1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
#include <algorithm>
#include <cassert>
#include <cctype>
#include "CategoryHandler.h"
#include "System/creg/STL_Map.h"
#include "System/StringUtil.h"
#include "System/Log/ILog.h"
CR_BIND(CCategoryHandler, )
CR_REG_METADATA(CCategoryHandler, (
CR_MEMBER(categories),
CR_MEMBER(firstUnused)
))
CCategoryHandler* CCategoryHandler::instance = NULL;
CCategoryHandler* CCategoryHandler::Instance() {
assert(instance != NULL);
return instance;
}
void CCategoryHandler::CreateInstance() {
if (instance == NULL) {
instance = new CCategoryHandler();
}
}
void CCategoryHandler::RemoveInstance()
{
delete instance;
instance = NULL;
}
unsigned int CCategoryHandler::GetCategory(std::string name)
{
StringTrimInPlace(name);
StringToLowerInPlace(name);
if (name.empty())
return 0; // the empty category
unsigned int cat = 0;
if (categories.find(name) == categories.end()) {
// this category is yet unknown
if (firstUnused >= CCategoryHandler::GetMaxCategories()) {
// skip this category
LOG_L(L_WARNING, "too many unit categories (%i), skipping %s",
firstUnused, name.c_str());
cat = 0;
} else {
// create the category (bit field value)
cat = (1 << firstUnused);
//LOG_L(L_DEBUG, "New unit-category %s #%i", name.c_str(), firstUnused);
}
// if (cat == 0), this will prevent further warnings for this category
categories[name] = cat;
firstUnused++;
} else {
// this category is already known
cat = categories[name];
}
return cat;
}
unsigned int CCategoryHandler::GetCategories(std::string names)
{
unsigned int ret = 0;
StringToLowerInPlace(names);
// split on ' '
std::stringstream namesStream(names);
std::string name;
while (std::getline(namesStream, name, ' ')) {
if (!name.empty()) {
ret |= GetCategory(name);
}
}
return ret;
}
std::vector<std::string> CCategoryHandler::GetCategoryNames(unsigned int bits) const
{
std::vector<std::string> names;
for (unsigned int bit = 1; bit != 0; bit = (bit << 1)) {
if ((bit & bits) != 0) {
for (auto it = categories.cbegin(); it != categories.cend(); ++it) {
if (it->second == bit) {
names.push_back(it->first);
}
}
}
}
return names;
}
|