Skip to content

Commit

Permalink
#5342: Save the vfs::FileInfo structure in the Doom3EntityClass insta…
Browse files Browse the repository at this point in the history
…nce, to be able to return the def file name later
  • Loading branch information
codereader committed Oct 2, 2020
1 parent c2881a4 commit f247e5c
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 39 deletions.
3 changes: 3 additions & 0 deletions include/ieclass.h
Expand Up @@ -312,6 +312,9 @@ class IEntityClass
* given entity class name. className is treated case-sensitively.
*/
virtual bool isOfType(const std::string& className) = 0;

// Returns the mod-relative path to the file this DEF was declared in
virtual std::string getDefFileName() = 0;
};

/**
Expand Down
1 change: 1 addition & 0 deletions plugins/script/interfaces/EClassInterface.cpp
Expand Up @@ -59,6 +59,7 @@ void EClassManagerInterface::registerInterface(py::module& scope, py::dict& glob
eclass.def("isNull", &ScriptEntityClass::isNull);
eclass.def("isOfType", &ScriptEntityClass::isOfType);
eclass.def("getAttribute", &ScriptEntityClass::getAttribute, py::return_value_policy::reference);
eclass.def("getDefFileName", &ScriptEntityClass::getDefFileName);

// Expose the entityclass visitor interface
py::class_<EntityClassVisitor, EntityClassVisitorWrapper> eclassVisitor(scope, "EntityClassVisitor");
Expand Down
21 changes: 15 additions & 6 deletions plugins/script/interfaces/EClassInterface.h
Expand Up @@ -22,26 +22,35 @@ class ScriptEntityClass
_emptyAttribute("text", "", "")
{}

operator const IEntityClassPtr&() const {
operator const IEntityClassPtr&() const
{
return _eclass;
}

// Returns a specific spawnarg from this entityDef, or "" if not found
const EntityClassAttribute& getAttribute(const std::string& name) {
if (_eclass == NULL) {
const EntityClassAttribute& getAttribute(const std::string& name)
{
if (!_eclass)
{
return _emptyAttribute;
}

return _eclass->getAttribute(name);
}

bool isNull() const {
return _eclass == NULL;
bool isNull() const
{
return !_eclass;
}

bool isOfType(const std::string& className)
{
return _eclass == NULL ? false : _eclass->isOfType(className);
return !_eclass ? false : _eclass->isOfType(className);
}

std::string getDefFileName()
{
return _eclass ? _eclass->getDefFileName() : std::string();
}
};

Expand Down
15 changes: 11 additions & 4 deletions radiantcore/eclass/Doom3EntityClass.cpp
Expand Up @@ -198,12 +198,13 @@ const std::string Doom3EntityClass::DefaultWireShader("<0.3 0.3 1>");
const std::string Doom3EntityClass::DefaultFillShader("(0.3 0.3 1)");
const Vector3 Doom3EntityClass::DefaultEntityColour(0.3, 0.3, 1);

Doom3EntityClass::Doom3EntityClass(const std::string& name) :
Doom3EntityClass(name, false)
Doom3EntityClass::Doom3EntityClass(const std::string& name, const vfs::FileInfo& fileInfo) :
Doom3EntityClass(name, fileInfo, false)
{}

Doom3EntityClass::Doom3EntityClass(const std::string& name, bool fixedSize)
Doom3EntityClass::Doom3EntityClass(const std::string& name, const vfs::FileInfo& fileInfo, bool fixedSize)
: _name(name),
_fileInfo(fileInfo),
_parent(nullptr),
_isLight(false),
_colour(-1, -1, -1),
Expand Down Expand Up @@ -347,7 +348,8 @@ void Doom3EntityClass::addAttribute(const EntityClassAttribute& attribute)

Doom3EntityClassPtr Doom3EntityClass::create(const std::string& name, bool brushes)
{
return std::make_shared<Doom3EntityClass>(name, !brushes);
vfs::FileInfo emptyFileInfo{ "def/", "_autogenerated_by_darkradiant_.def" };
return std::make_shared<Doom3EntityClass>(name, emptyFileInfo, !brushes);
}

// Enumerate entity class attributes
Expand Down Expand Up @@ -461,6 +463,11 @@ bool Doom3EntityClass::isOfType(const std::string& className)
return false;
}

std::string Doom3EntityClass::getDefFileName()
{
return _fileInfo.fullPath();
}

// Find a single attribute
EntityClassAttribute& Doom3EntityClass::getAttribute(const std::string& name)
{
Expand Down
13 changes: 9 additions & 4 deletions radiantcore/eclass/Doom3EntityClass.h
Expand Up @@ -2,6 +2,7 @@

#include "ieclass.h"
#include "irender.h"
#include "ifilesystem.h"

#include "math/Vector3.h"
#include "math/AABB.h"
Expand Down Expand Up @@ -45,6 +46,9 @@ class Doom3EntityClass
// The name of this entity class
std::string _name;

// Source file information
vfs::FileInfo _fileInfo;

// Parent class pointer (or NULL)
IEntityClass* _parent;

Expand Down Expand Up @@ -114,7 +118,6 @@ class Doom3EntityClass
void setIsLight(bool val);

public:

/**
* Static function to create a default entity class.
*
Expand All @@ -134,7 +137,7 @@ class Doom3EntityClass
*
* This eclass will have isFixedSize set to false.
*/
Doom3EntityClass(const std::string& name);
Doom3EntityClass(const std::string& name, const vfs::FileInfo& fileInfo);

/**
* Constructor.
Expand All @@ -145,9 +148,9 @@ class Doom3EntityClass
* @param fixedSize
* whether this entity has a fixed size.
*/
Doom3EntityClass(const std::string& name, bool fixedSize);
Doom3EntityClass(const std::string& name, const vfs::FileInfo& fileInfo, bool fixedSize);

~Doom3EntityClass();
virtual ~Doom3EntityClass();

/// Add a new attribute
void addAttribute(const EntityClassAttribute& attribute);
Expand All @@ -174,6 +177,8 @@ class Doom3EntityClass

bool isOfType(const std::string& className) override;

std::string getDefFileName() override;

/// Set a model on this entity class.
void setModelPath(const std::string& path) {
_fixedSize = true;
Expand Down
28 changes: 10 additions & 18 deletions radiantcore/eclass/EClassManager.cpp
Expand Up @@ -71,17 +71,15 @@ IEntityClassPtr EClassManager::findOrInsert(const std::string& name, bool has_br
Doom3EntityClassPtr EClassManager::findInternal(const std::string& name)
{
// Find the EntityClass in the map.
EntityClasses::const_iterator i = _entityClasses.find(name);
auto i = _entityClasses.find(name);

return i != _entityClasses.end() ? i->second : Doom3EntityClassPtr();
}

Doom3EntityClassPtr EClassManager::insertUnique(const Doom3EntityClassPtr& eclass)
{
// Try to insert the eclass
std::pair<EntityClasses::iterator, bool> i = _entityClasses.insert(
EntityClasses::value_type(eclass->getName(), eclass)
);
auto i = _entityClasses.emplace(eclass->getName(), eclass);

// Return the pointer to the inserted eclass
return i.first->second;
Expand Down Expand Up @@ -135,7 +133,7 @@ void EClassManager::parseDefFiles()
ScopedDebugTimer timer("EntityDefs parsed: ");
GlobalFileSystem().forEachFile(
"def/", "def",
[&](const vfs::FileInfo& fileInfo) { parseFile(fileInfo.name); }
[&](const vfs::FileInfo& fileInfo) { parseFile(fileInfo); }
);
}
}
Expand Down Expand Up @@ -336,7 +334,7 @@ void EClassManager::onFileSystemShutdown()

// Parse the provided stream containing the contents of a single .def file.
// Extract all entitydefs and create objects accordingly.
void EClassManager::parse(TextInputStream& inStr, const std::string& modDir)
void EClassManager::parse(TextInputStream& inStr, const vfs::FileInfo& fileInfo, const std::string& modDir)
{
// Construct a tokeniser for the stream
std::istream is(&inStr);
Expand All @@ -355,16 +353,12 @@ void EClassManager::parse(TextInputStream& inStr, const std::string& modDir)

// Ensure that an Entity class with this name already exists
// When reloading entityDef declarations, most names will already be registered
EntityClasses::iterator i = _entityClasses.find(sName);
auto i = _entityClasses.find(sName);

if (i == _entityClasses.end())
{
// Not existing yet, allocate a new class
Doom3EntityClassPtr entityClass(new eclass::Doom3EntityClass(sName));

std::pair<EntityClasses::iterator, bool> result = _entityClasses.insert(
EntityClasses::value_type(sName, entityClass)
);
auto result = _entityClasses.emplace(sName, std::make_shared<Doom3EntityClass>(sName, fileInfo));

i = result.first;
}
Expand Down Expand Up @@ -430,22 +424,20 @@ void EClassManager::parse(TextInputStream& inStr, const std::string& modDir)
}
}

void EClassManager::parseFile(const std::string& filename)
void EClassManager::parseFile(const vfs::FileInfo& fileInfo)
{
const std::string fullname = "def/" + filename;

ArchiveTextFilePtr file = GlobalFileSystem().openTextFile(fullname);
auto file = GlobalFileSystem().openTextFile(fileInfo.fullPath());

if (!file) return;

try
{
// Parse entity defs from the file
parse(file->getInputStream(), file->getModName());
parse(file->getInputStream(), fileInfo, file->getModName());
}
catch (parser::ParseException& e)
{
rError() << "[eclassmgr] failed to parse " << filename
rError() << "[eclassmgr] failed to parse " << fileInfo.fullPath()
<< " (" << e.what() << ")" << std::endl;
}
}
Expand Down
14 changes: 7 additions & 7 deletions radiantcore/eclass/EClassManager.h
Expand Up @@ -77,15 +77,15 @@ class EClassManager :
void reloadDefs() override;

// RegisterableModule implementation
virtual const std::string& getName() const override;
virtual const StringSet& getDependencies() const override;
virtual void initialiseModule(const IApplicationContext& ctx) override;
virtual void shutdownModule() override;
const std::string& getName() const override;
const StringSet& getDependencies() const override;
void initialiseModule(const IApplicationContext& ctx) override;
void shutdownModule() override;

private:
// Method loading the DEF files
void parseFile(const std::string& filename);
void parseFile(const vfs::FileInfo& fileInfo);

private:
// Since loading is happening in a worker thread, we need to ensure
// that it's done loading before accessing any defs or models.
void ensureDefsLoaded();
Expand All @@ -99,7 +99,7 @@ class EClassManager :
Doom3EntityClassPtr findInternal(const std::string& name);

// Parses the given inputstream for DEFs.
void parse(TextInputStream& inStr, const std::string& modDir);
void parse(TextInputStream& inStr, const vfs::FileInfo& fileInfo, const std::string& modDir);

// Recursively resolves the inheritance of the model defs
void resolveModelInheritance(const std::string& name, const Doom3ModelDefPtr& model);
Expand Down

0 comments on commit f247e5c

Please sign in to comment.