Skip to content

Commit

Permalink
#5977: Some more precautions, code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Jun 26, 2022
1 parent 9eff828 commit f1cb620
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 103 deletions.
11 changes: 2 additions & 9 deletions radiantcore/decl/DeclarationFileParser.cpp
Expand Up @@ -9,7 +9,7 @@ namespace decl

namespace
{
inline std::string getBlockTypeName(const std::string& declaration)
std::string getBlockTypeName(const std::string& declaration)
{
auto spacePos = declaration.find(' ');

Expand All @@ -18,7 +18,7 @@ namespace
return string::trim_copy(declaration.substr(0, spacePos), " \t"); // remove all tabs and spaces
}

inline DeclarationBlockSyntax createBlock(const parser::BlockTokeniser::Block& block,
DeclarationBlockSyntax createBlock(const parser::BlockTokeniser::Block& block,
const vfs::FileInfo& fileInfo, const std::string& modName)
{
auto spacePos = block.name.find(' ');
Expand Down Expand Up @@ -47,9 +47,6 @@ std::map<Type, std::vector<DeclarationBlockSyntax>>& DeclarationFileParser::getP

void DeclarationFileParser::parse(std::istream& stream, const vfs::FileInfo& fileInfo, const std::string& modDir)
{
#if 0
auto& declFile = _parsedFiles.emplace_back(DeclarationFile{ fileInfo.fullPath(), _defaultDeclType });
#endif
// Cut the incoming stream into declaration blocks
parser::BasicDefBlockTokeniser<std::istream> tokeniser(stream);

Expand All @@ -64,10 +61,6 @@ void DeclarationFileParser::parse(std::istream& stream, const vfs::FileInfo& fil
auto declType = determineBlockType(blockSyntax);
auto& blockList = _parsedBlocks.try_emplace(declType).first->second;
blockList.emplace_back(std::move(blockSyntax));
#if 0
// Add this declaration to the parsed file
//declFile.declarations.emplace_back(declType, block.name);
#endif
}
}

Expand Down
6 changes: 0 additions & 6 deletions radiantcore/decl/DeclarationFileParser.h
Expand Up @@ -15,9 +15,6 @@ class DeclarationFileParser

std::map<std::string, Type> _typeMapping;

#if 0
std::map<std::string, DeclarationFile> _parsedFiles;
#endif
std::map<Type, std::vector<DeclarationBlockSyntax>> _parsedBlocks;

public:
Expand All @@ -26,9 +23,6 @@ class DeclarationFileParser
void parse(std::istream& stream, const vfs::FileInfo& fileInfo, const std::string& modDir);

std::map<Type, std::vector<DeclarationBlockSyntax>>& getParsedBlocks();
#if 0
const std::map<std::string, DeclarationFile>& getParsedFiles() const;
#endif

private:
Type determineBlockType(const DeclarationBlockSyntax& block);
Expand Down
1 change: 0 additions & 1 deletion radiantcore/decl/DeclarationFolderParser.h
Expand Up @@ -2,7 +2,6 @@

#include "DeclarationFile.h"
#include "DeclarationFileParser.h"
#include "ideclmanager.h"

#include "parser/ThreadedDeclParser.h"

Expand Down
104 changes: 26 additions & 78 deletions radiantcore/decl/DeclarationManager.cpp
Expand Up @@ -129,6 +129,10 @@ void DeclarationManager::doWithDeclarations(Type type, const std::function<void(

void DeclarationManager::reloadDecarations()
{
// Don't allow reloadDecls to be run before the startup phase is complete
waitForTypedParsersToFinish();

// Don't allow more than one simultaneous reloadDecls run
if (_reparseInProgress) return;

util::ScopedBoolLock reparseLock(_reparseInProgress);
Expand Down Expand Up @@ -166,47 +170,6 @@ void DeclarationManager::reloadDecarations()
}
}
}
#if 0
std::lock_guard fileLock(_parsedFileLock);
std::lock_guard parserLock(_creatorLock);

for (auto& [type, files] : _parsedFilesByDefaultType)
{
DeclarationFileParser parser(type, getTypenameMapping());

for (auto& file : files)
{
auto vfsFile = GlobalFileSystem().openTextFile(file.fullPath);

if (!vfsFile) continue;

auto fileInfo = GlobalFileSystem().getFileInfo(file.fullPath);

try
{
// Parse entity defs from the file
std::istream stream(&vfsFile->getInputStream());
parser.parse(stream, fileInfo, vfsFile->getModName());
}
catch (parser::ParseException& e)
{
rError() << "[DeclParser] Failed to parse " << fileInfo.fullPath()
<< " (" << e.what() << ")" << std::endl;
}

const auto& newlyParsedFile = parser.getParsedFiles().find(file.fullPath);

// Invalidate all declarations that have been removed from the file
handleMissingDecls(file, newlyParsedFile);
}

// Submit the changes
processParsedBlocks(parser.getParsedBlocks());
}

// Process the list of unrecognised blocks (from this and any previous run)
handleUnrecognisedBlocks();
#endif

std::lock_guard folderLock(_registeredFoldersLock);

Expand All @@ -217,6 +180,24 @@ void DeclarationManager::reloadDecarations()
}
}

void DeclarationManager::waitForTypedParsersToFinish()
{
auto declLock = std::make_unique<std::lock_guard<std::recursive_mutex>>(_declarationLock);

for (auto& [_, decls] : _declarationsByType)
{
if (!decls.parser) continue;

// Release the lock to give the thread a chance to finish
declLock.reset();

decls.parser->ensureFinished(); // blocks
decls.parser.reset();

declLock = std::make_unique<std::lock_guard<std::recursive_mutex>>(_declarationLock);
}
}

void DeclarationManager::runParsersForAllFolders()
{
std::vector<std::unique_ptr<DeclarationFolderParser>> parsers;
Expand Down Expand Up @@ -246,24 +227,8 @@ sigc::signal<void>& DeclarationManager::signal_DeclsReloaded(Type type)
}

void DeclarationManager::onParserFinished(Type parserType,
const std::map<Type, std::vector<DeclarationBlockSyntax>>& parsedBlocks)
std::map<Type, std::vector<DeclarationBlockSyntax>>& parsedBlocks)
{
#if 0
// Sort all parsed files into the large list
{
std::lock_guard lock(_parsedFileLock);

// Merge all parsed files into the main set
for (const auto& [_, parsedFile] : parsedFiles)
{
auto& fileSet = _parsedFilesByDefaultType.try_emplace(
parsedFile.defaultDeclType, std::vector<DeclarationFile>()).first->second;

fileSet.emplace(parsedFile);
}
}
#endif

// Sort all parsed blocks into our main dictionary
// unrecognised blocks will be pushed to _unrecognisedBlocks
processParsedBlocks(parsedBlocks);
Expand All @@ -275,17 +240,15 @@ void DeclarationManager::onParserFinished(Type parserType,
signal_DeclsReloaded(parserType).emit();
}

void DeclarationManager::processParsedBlocks(const std::map<Type, std::vector<DeclarationBlockSyntax>>& parsedBlocks)
void DeclarationManager::processParsedBlocks(std::map<Type, std::vector<DeclarationBlockSyntax>>& parsedBlocks)
{
std::lock_guard declLock(_declarationLock);
std::lock_guard creatorLock(_creatorLock);

// Coming back from a parser thread, sort the parsed decls into the main dictionary
for (auto& pair : parsedBlocks)
for (auto& [type, blocks] : parsedBlocks)
{
auto type = pair.first;

for (const auto& block : pair.second)
for (auto& block : blocks)
{
if (type == Type::Undetermined)
{
Expand Down Expand Up @@ -369,18 +332,6 @@ void DeclarationManager::handleUnrecognisedBlocks()
}
}

void DeclarationManager::InsertDeclaration(NamedDeclarations& map, IDeclaration::Ptr&& declaration)
{
auto type = declaration->getDeclType();
auto result = map.try_emplace(declaration->getDeclName(), std::move(declaration));

if (!result.second)
{
rWarning() << "[DeclParser]: " << getTypeName(type) << " " <<
result.first->second->getDeclName() << " has already been declared" << std::endl;
}
}

const std::string& DeclarationManager::getName() const
{
static std::string _name(MODULE_DECLMANAGER);
Expand Down Expand Up @@ -425,9 +376,6 @@ void DeclarationManager::shutdownModule()

// All parsers have finished, clear the structure, no need to lock anything
_registeredFolders.clear();
#if 0
_parsedFilesByDefaultType.clear();
#endif
_unrecognisedBlocks.clear();
_declarationsByType.clear();
_creatorsByTypename.clear();
Expand Down
13 changes: 4 additions & 9 deletions radiantcore/decl/DeclarationManager.h
Expand Up @@ -31,11 +31,6 @@ class DeclarationManager :
std::vector<RegisteredFolder> _registeredFolders;
std::recursive_mutex _registeredFoldersLock;

#if 0
std::map<Type, std::set<DeclarationFile>> _parsedFilesByDefaultType;
std::recursive_mutex _parsedFileLock;
#endif

struct Declarations
{
// The decl library
Expand Down Expand Up @@ -73,17 +68,17 @@ class DeclarationManager :

// Invoked once a parser thread has finished. It will move its data over to here.
void onParserFinished(Type parserType,
const std::map<Type, std::vector<DeclarationBlockSyntax>>& parsedBlocks);

static void InsertDeclaration(NamedDeclarations& map, IDeclaration::Ptr&& declaration);
std::map<Type, std::vector<DeclarationBlockSyntax>>& parsedBlocks);

private:
void runParsersForAllFolders();
void waitForTypedParsersToFinish();

// Attempts to resolve the block type of the given block, returns true on success, false otherwise.
// Stores the determined type in the given reference.
std::map<std::string, Type> getTypenameMapping();
bool tryDetermineBlockType(const DeclarationBlockSyntax& block, Type& type);
void processParsedBlocks(const std::map<Type, std::vector<DeclarationBlockSyntax>>& parsedBlocks);
void processParsedBlocks(std::map<Type, std::vector<DeclarationBlockSyntax>>& parsedBlocks);
void createOrUpdateDeclaration(Type type, const DeclarationBlockSyntax& block);
void doWithDeclarations(Type type, const std::function<void(const NamedDeclarations&)>& action);
void handleUnrecognisedBlocks();
Expand Down

0 comments on commit f1cb620

Please sign in to comment.