Skip to content

Commit

Permalink
#5342: Make sound shader objects remember the VFS location of the fil…
Browse files Browse the repository at this point in the history
…e they're defined in
  • Loading branch information
codereader committed Oct 1, 2020
1 parent 9c6ac11 commit 0782620
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 45 deletions.
7 changes: 7 additions & 0 deletions include/isound.h
Expand Up @@ -61,6 +61,7 @@ class ISoundShader :
public ModResource
{
public:
virtual ~ISoundShader() {}

/// Get the name of the shader
virtual std::string getName() const = 0;
Expand All @@ -74,6 +75,12 @@ class ISoundShader :
// angua: get the display folder for sorting the sounds in the sound chooser window
virtual const std::string& getDisplayFolder() const = 0;

// Returns the mod-relative path to the file this shader is defined in
virtual std::string getShaderFilePath() const = 0;

// Returns the raw sound shader definition text
virtual std::string getDefinition() const = 0;

};
typedef std::shared_ptr<ISoundShader> ISoundShaderPtr;

Expand Down
46 changes: 20 additions & 26 deletions plugins/sound/SoundFileLoader.h
Expand Up @@ -41,7 +41,7 @@ class SoundFileLoader
}

// Accept a stream of shaders to parse
void parseShadersFromStream(std::istream& contents,
void parseShadersFromStream(std::istream& contents, const vfs::FileInfo& fileInfo,
const std::string& modName)
{
// Construct a DefTokeniser to tokenise the string into sound shader
Expand All @@ -54,12 +54,8 @@ class SoundFileLoader
parser::BlockTokeniser::Block block = tok.nextBlock();

// Create a new shader with this name
std::pair<SoundManager::ShaderMap::iterator, bool> result;
result = _shaders.insert(
SoundManager::ShaderMap::value_type(
block.name,
std::make_shared<SoundShader>(block.name, block.contents, modName)
)
auto result = _shaders.emplace(block.name,
std::make_shared<SoundShader>(block.name, block.contents, fileInfo, modName)
);

if (!result.second) {
Expand All @@ -81,31 +77,29 @@ class SoundFileLoader
/**
* Functor operator.
*/
void operator()(const std::string& filename)
void parseShaderFile(const vfs::FileInfo& fileInfo)
{
// Open the .sndshd file and get its contents as a std::string
ArchiveTextFilePtr file =
GlobalFileSystem().openTextFile(SOUND_FOLDER + filename);
auto file = GlobalFileSystem().openTextFile(SOUND_FOLDER + fileInfo.name);

// Parse contents of file if it was opened successfully
if (file)
{
std::istream is(&(file->getInputStream()));

try
{
parseShadersFromStream(is, file->getModName());
}
catch (parser::ParseException& ex)
{
rError() << "[sound]: Error while parsing " << filename <<
": " << ex.what() << std::endl;
}
}
else
if (!file)
{
rWarning() << "[sound] Warning: unable to open \""
<< filename << "\"" << std::endl;
<< fileInfo.name << "\"" << std::endl;
return;
}

std::istream is(&(file->getInputStream()));

try
{
parseShadersFromStream(is, fileInfo, file->getModName());
}
catch (parser::ParseException & ex)
{
rError() << "[sound]: Error while parsing " << fileInfo.name <<
": " << ex.what() << std::endl;
}
}
};
Expand Down
6 changes: 3 additions & 3 deletions plugins/sound/SoundManager.cpp
Expand Up @@ -14,7 +14,7 @@ namespace sound
// Constructor
SoundManager::SoundManager() :
_defLoader(std::bind(&SoundManager::loadShadersFromFilesystem, this)),
_emptyShader(new SoundShader("", ""))
_emptyShader(new SoundShader("", "", vfs::FileInfo(), ""))
{}

// Enumerate shaders
Expand Down Expand Up @@ -123,15 +123,15 @@ const StringSet& SoundManager::getDependencies() const

void SoundManager::loadShadersFromFilesystem()
{
ShaderMapPtr foundShaders = std::make_shared<ShaderMap>();
auto foundShaders = std::make_shared<ShaderMap>();

// Pass a SoundFileLoader to the filesystem
SoundFileLoader loader(*foundShaders);

GlobalFileSystem().forEachFile(
SOUND_FOLDER, // directory
"sndshd", // required extension
[&](const vfs::FileInfo& fileInfo) { loader(fileInfo.name); }, // loader callback
std::bind(&SoundFileLoader::parseShaderFile, loader, std::placeholders::_1), // loader callback
99 // max depth
);

Expand Down
4 changes: 2 additions & 2 deletions plugins/sound/SoundManager.h
Expand Up @@ -16,7 +16,7 @@ class SoundManager : public ISoundManager
public: /* TYPES */

// Map of named sound shaders
typedef std::map<std::string, SoundShaderPtr> ShaderMap;
typedef std::map<std::string, SoundShader::Ptr> ShaderMap;
typedef std::shared_ptr<ShaderMap> ShaderMapPtr;

private: /* FIELDS */
Expand All @@ -28,7 +28,7 @@ class SoundManager : public ISoundManager
// takes care of the worker thread
util::ThreadedDefLoader<void> _defLoader;

SoundShaderPtr _emptyShader;
SoundShader::Ptr _emptyShader;

// The helper class for playing the sounds
std::shared_ptr<SoundPlayer> _soundPlayer;
Expand Down
11 changes: 11 additions & 0 deletions plugins/sound/SoundShader.cpp
Expand Up @@ -22,9 +22,11 @@ struct SoundShader::ParsedContents

SoundShader::SoundShader(const std::string& name,
const std::string& blockContents,
const vfs::FileInfo& fileInfo,
const std::string& modName)
: _name(name),
_blockContents(blockContents),
_fileInfo(fileInfo),
_modName(modName)
{ }

Expand Down Expand Up @@ -91,5 +93,14 @@ const std::string& SoundShader::getDisplayFolder() const
return _contents->displayFolder;
}

std::string SoundShader::getShaderFilePath() const
{
return _fileInfo.fullPath();
}

std::string SoundShader::getDefinition() const
{
return _blockContents;
}

} // namespace sound
32 changes: 18 additions & 14 deletions plugins/sound/SoundShader.h
@@ -1,14 +1,16 @@
#pragma once

#include "isound.h"

#include <memory>

#include "isound.h"
#include "ifilesystem.h"

namespace sound
{

/// Representation of a single sound shader.
class SoundShader : public ISoundShader
class SoundShader :
public ISoundShader
{
// Name of the shader
std::string _name;
Expand All @@ -20,6 +22,8 @@ class SoundShader : public ISoundShader
struct ParsedContents;
mutable std::unique_ptr<ParsedContents> _contents;

vfs::FileInfo _fileInfo;

// The modname (ModResource implementation)
std::string _modName;

Expand All @@ -28,24 +32,24 @@ class SoundShader : public ISoundShader
void parseDefinition() const;

public:
using Ptr = std::shared_ptr<SoundShader>;

/// Constructor.
SoundShader(const std::string& name,
const std::string& blockContents,
const vfs::FileInfo& fileInfo,
const std::string& modName = "base");
~SoundShader();

virtual ~SoundShader();

// ISoundShader implementation
SoundRadii getRadii() const;
std::string getName() const { return _name; }
SoundFileList getSoundFileList() const;
std::string getModName() const { return _modName; }
const std::string& getDisplayFolder() const;
SoundRadii getRadii() const override;
std::string getName() const override { return _name; }
SoundFileList getSoundFileList() const override;
std::string getModName() const override { return _modName; }
const std::string& getDisplayFolder() const override;
std::string getShaderFilePath() const override;
std::string getDefinition() const override;
};

/**
* Shared pointer type.
*/
typedef std::shared_ptr<SoundShader> SoundShaderPtr;

}

0 comments on commit 0782620

Please sign in to comment.