Skip to content

Commit

Permalink
libcore|libgui|ScriptedInfo: Inheritance considered when looking up r…
Browse files Browse the repository at this point in the history
…elative paths

Relative file paths in ScriptedInfo records are normally relative to
the file where the records are read from. However, when inheriting
from records in other files, relative paths might still refer to
their original location.

These changes allow looking up files in relation to all the inherited
source location.
  • Loading branch information
skyjake committed Mar 12, 2016
1 parent 444ec87 commit 1dc29d4
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 27 deletions.
16 changes: 9 additions & 7 deletions doomsday/sdk/libcore/include/de/data/infobank.h
Expand Up @@ -92,17 +92,19 @@ class DENG2_PUBLIC InfoBank : public Bank, public IObject
String bankRootPath() const;

/**
* Determines what relatives paths should be relative to, given a specific context.
* This should be used when resolving paths in ScriptedInfo records.
* Resolves a relative path into an absoluate path in the context of @a context.
* This should be used when processing paths in ScriptedInfo records.
*
* In practice, checks if the context has a "__source__" specified; if not, returns
* the root path of the bank.
* In practice, first checks if the context has a "__source__" specified. If the
* relative path cannot be found, also checks the possible inherited source locations.
* If source information is not specified, uses the the root path of the bank.
*
* @param context Namespace to use as context.
* @param context Namespace to use as context.
* @param relativePath Relative path to resolve.
*
* @return Path that relative paths should be resolved with.
* @return Absolute path.
*/
String relativeToPath(Record const &context) const;
String absolutePathInContext(Record const &context, String const &relativePath) const;

// Implements IObject.
Record &objectNamespace();
Expand Down
2 changes: 2 additions & 0 deletions doomsday/sdk/libcore/include/de/scriptsys/scriptedinfo.h
Expand Up @@ -245,6 +245,8 @@ class DENG2_PUBLIC ScriptedInfo : public IObject
/// Name of a special variable where the block type is stored.
static String const VAR_BLOCK_TYPE;

static String const VAR_INHERITED_SOURCES;

private:
DENG2_PRIVATE(d)
};
Expand Down
17 changes: 13 additions & 4 deletions doomsday/sdk/libcore/src/data/infobank.cpp
Expand Up @@ -176,11 +176,20 @@ String InfoBank::bankRootPath() const
return d->relativeToPath;
}

String InfoBank::relativeToPath(Record const &context) const
String InfoBank::absolutePathInContext(Record const &context, String const &relativePath) const
{
String const root = ScriptedInfo::absolutePathInContext(context, "");
if(root.isEmpty()) return bankRootPath();
return root;
if(Path(relativePath).isAbsolute())
{
// Already absolute.
return relativePath;
}

String const path = ScriptedInfo::absolutePathInContext(context, relativePath);
if(path == relativePath)
{
return bankRootPath() / relativePath;
}
return path;
}

} // namespace de
41 changes: 37 additions & 4 deletions doomsday/sdk/libcore/src/scriptsys/scriptedinfo.cpp
Expand Up @@ -32,6 +32,7 @@ String const ScriptedInfo::SCRIPT = "script";
String const ScriptedInfo::BLOCK_GROUP = "group";
String const ScriptedInfo::VAR_SOURCE = "__source__";
String const ScriptedInfo::VAR_BLOCK_TYPE = "__type__";
String const ScriptedInfo::VAR_INHERITED_SOURCES = "__inheritedSources__"; // array

static String const BLOCK_NAMESPACE = "namespace";
static String const BLOCK_SCRIPT = ScriptedInfo::SCRIPT;
Expand Down Expand Up @@ -167,9 +168,20 @@ DENG2_PIMPL(ScriptedInfo)
DENG2_ASSERT(!targetName.isEmpty());

// Copy all present members of the target record.
ns.subrecord(varName)
.copyMembersFrom(ns[targetName].value<RecordValue>().dereference(),
Record::IgnoreDoubleUnderscoreMembers);
Record const &src = ns[targetName].value<RecordValue>().dereference();
Record &dest = ns.subrecord(varName);
dest.copyMembersFrom(src, Record::IgnoreDoubleUnderscoreMembers);

// Append the inherited source location.
if(src.hasMember(VAR_SOURCE))
{
if(!dest.hasMember(VAR_INHERITED_SOURCES))
{
dest.addArray(VAR_INHERITED_SOURCES);
}
dest[VAR_INHERITED_SOURCES].value<ArrayValue>()
.add(new TextValue(ScriptedInfo::sourcePathAndLine(src).first));
}
}
}

Expand Down Expand Up @@ -558,8 +570,29 @@ String ScriptedInfo::absolutePathInContext(Record const &context, String const &
{
auto const sourceLocation = Info::sourceLineTable().sourcePathAndLineNumber(
context.getui(VAR_SOURCE));
return sourceLocation.first.fileNamePath() / relativePath;

String absPath = sourceLocation.first.fileNamePath() / relativePath;
if(!App::rootFolder().has(absPath))
{
// As a fallback, look for possible inherited locations.
if(context.has(VAR_INHERITED_SOURCES))
{
// Look in reverse so the latest inherited locations are checked first.
auto const &elems = context.geta(VAR_INHERITED_SOURCES);
for(int i = elems.size() - 1; i >= 0; --i)
{
String inheritedPath = elems.at(i).asText().fileNamePath() / relativePath;
if(App::rootFolder().has(inheritedPath))
{
return inheritedPath;
}
}
}
}
return absPath;
}

// The relation is unknown.
return relativePath;
}

Expand Down
2 changes: 1 addition & 1 deletion doomsday/sdk/libgui/src/audio/waveformbank.cpp
Expand Up @@ -81,7 +81,7 @@ Waveform const &WaveformBank::waveform(DotPath const &id) const
Bank::ISource *WaveformBank::newSourceFromInfo(String const &id)
{
Record const &def = info()[id];
return new Instance::Source(relativeToPath(def) / def["path"]);
return new Instance::Source(absolutePathInContext(def, def["path"]));
}

Bank::IData *WaveformBank::loadFromSource(ISource &source)
Expand Down
15 changes: 6 additions & 9 deletions doomsday/sdk/libgui/src/graphics/glshaderbank.cpp
Expand Up @@ -137,8 +137,6 @@ DENG2_PIMPL(GLShaderBank)
typedef QMap<String, GLShader *> Shaders; // path -> shader
Shaders shaders;

//String relativeToPath;

Instance(Public *i) : Base(i)
{}

Expand Down Expand Up @@ -180,7 +178,6 @@ GLShaderBank::GLShaderBank() : InfoBank("GLShaderBank"), d(new Instance(this))
void GLShaderBank::addFromInfo(File const &file)
{
LOG_AS("GLShaderBank");
//d->relativeToPath = file.path().fileNamePath();
parse(file);
addFromInfoBlocks("shader");
}
Expand Down Expand Up @@ -231,11 +228,11 @@ Bank::ISource *GLShaderBank::newSourceFromInfo(String const &id)
}
else if(def.has("path.vertex"))
{
vtx = ShaderSource(relativeToPath(def) / def["path.vertex"], ShaderSource::FilePath);
vtx = ShaderSource(absolutePathInContext(def, def["path.vertex"]), ShaderSource::FilePath);
}
else if(def.has("path"))
{
vtx = ShaderSource(relativeToPath(def) / def["path"] + ".vsh", ShaderSource::FilePath);
vtx = ShaderSource(absolutePathInContext(def, def.gets("path") + ".vsh"), ShaderSource::FilePath);
}

// Fragment shader definition.
Expand All @@ -245,11 +242,11 @@ Bank::ISource *GLShaderBank::newSourceFromInfo(String const &id)
}
else if(def.has("path.fragment"))
{
frag = ShaderSource(relativeToPath(def) / def["path.fragment"], ShaderSource::FilePath);
frag = ShaderSource(absolutePathInContext(def, def["path.fragment"]), ShaderSource::FilePath);
}
else if(def.has("path"))
{
frag = ShaderSource(relativeToPath(def) / def["path"] + ".fsh", ShaderSource::FilePath);
frag = ShaderSource(absolutePathInContext(def, def.gets("path") + ".fsh"), ShaderSource::FilePath);
}

// Additional shaders to append to the main source.
Expand All @@ -259,7 +256,7 @@ Bank::ISource *GLShaderBank::newSourceFromInfo(String const &id)
auto const &incs = def["include.vertex"].value().as<ArrayValue>().elements();
for(int i = incs.size() - 1; i >= 0; --i)
{
vtx.insertFromFile(relativeToPath(def) / incs.at(i)->asText());
vtx.insertFromFile(absolutePathInContext(def, incs.at(i)->asText()));
}
}
if(def.has("include.fragment"))
Expand All @@ -268,7 +265,7 @@ Bank::ISource *GLShaderBank::newSourceFromInfo(String const &id)
auto const &incs = def["include.fragment"].value().as<ArrayValue>().elements();
for(int i = incs.size() - 1; i >= 0; --i)
{
frag.insertFromFile(relativeToPath(def) / incs.at(i)->asText());
frag.insertFromFile(absolutePathInContext(def, incs.at(i)->asText()));
}
}

Expand Down
4 changes: 2 additions & 2 deletions doomsday/sdk/libgui/src/graphics/imagebank.cpp
Expand Up @@ -13,7 +13,7 @@
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details. You should have received a copy of
* the GNU Lesser General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
* http://www.gnu.org/licenses</small>
*/

#include "de/ImageBank"
Expand Down Expand Up @@ -86,7 +86,7 @@ Image const &ImageBank::image(DotPath const &path) const
Bank::ISource *ImageBank::newSourceFromInfo(String const &id)
{
Record const &def = info()[id];
return new Instance::ImageSource(relativeToPath(def) / def["path"]);
return new Instance::ImageSource(absolutePathInContext(def, def["path"]));
}

Bank::IData *ImageBank::loadFromSource(ISource &source)
Expand Down

0 comments on commit 1dc29d4

Please sign in to comment.