Implement skin inheritance via <% .extends skinname %>. Lookup code is now incredibly convoluted for what it does and needs some streamlining.

This commit is contained in:
hns 2009-04-06 05:54:26 +00:00
parent ea2d20c55f
commit 8b65614827
3 changed files with 54 additions and 14 deletions

View file

@ -341,19 +341,25 @@ public final class Prototype {
skin = Skin.getSkin(res, app);
if (skin.hasMainskin())
break;
String extendz = skin.getExtends();
if (extendz != null && extendz != skinName)
return getSkin(extendz, null, null);
res = res.getOverloadedResource();
}
if (parentName != null) {
Skin parentSkin = null;
Resource parent = skinMap.getResource(parentName);
while (parent != null) {
parentSkin = Skin.getSkin(parent, app);
Resource parentResource = skinMap.getResource(parentName);
while (parentResource != null) {
parentSkin = Skin.getSkin(parentResource, app);
if (parentSkin.hasSubskin(subName))
break;
parent = parent.getOverloadedResource();
String extendz = parentSkin.getExtends();
if (extendz != null && extendz != parentName)
return getSkin(extendz, extendz, subName);
parentResource = parentResource.getOverloadedResource();
}
if (parent != null) {
if (res != null && app.getResourceComparator().compare(res, parent) > 0)
if (parentResource != null) {
if (res != null && app.getResourceComparator().compare(res, parentResource) > 0)
return skin;
else
return parentSkin.getSubskin(subName);

View file

@ -42,6 +42,8 @@ public final class Skin {
private HashSet sandbox;
private HashMap subskins;
private Skin parentSkin = this;
private String extendz = null;
private boolean hasContent = false;
static private final int PARSE_MACRONAME = 0;
static private final int PARSE_PARAM = 1;
@ -157,10 +159,16 @@ public final class Skin {
length = i;
break;
} else {
if (!macro.isCommentMacro) {
hasContent = true;
}
partBuffer.add(macro);
}
i = macro.end - 1;
} else {
if (!hasContent && !Character.isWhitespace(source[i])){
hasContent = true;
}
escape = source[i] == '\\' && !escape;
}
}
@ -181,7 +189,7 @@ public final class Skin {
* @return true if this skin contains a main skin
*/
public boolean hasMainskin() {
return length - offset > 0 || subskins == null;
return hasContent;
}
/**
@ -212,6 +220,10 @@ public final class Skin {
(String[]) subskins.keySet().toArray(new String[0]);
}
public String getExtends() {
return extendz;
}
/**
* Get the raw source text this skin was parsed from
*/
@ -328,8 +340,6 @@ public final class Skin {
}
}
class Macro {
final int start, end;
String name;
@ -389,6 +399,18 @@ public final class Skin {
handlerType = HANDLER_PARAM;
}
}
if (".extends".equals(name)) {
if (parentSkin != Skin.this) {
throw new RuntimeException("Found .extends in subskin");
}
if (positionalParams == null || positionalParams.size() < 1
|| !(positionalParams.get(0) instanceof String)) {
throw new RuntimeException(".extends requires an unnamed string parameter");
}
extendz = (String) positionalParams.get(0);
isCommentMacro = true; // don't render
}
}
private int parse(int macroOffset, boolean lenient) {

View file

@ -51,7 +51,7 @@ public final class SkinManager implements FilenameFilter {
Skin skin;
Prototype proto = prototype;
// if name contains dot, this might be a substring of some other string
// if name contains #, this may be a subskin of some other skin
String parentName = null, subskinName = null;
int hash = skinname.indexOf('#');
if (hash > -1) {
@ -65,16 +65,28 @@ public final class SkinManager implements FilenameFilter {
if (skinpath != null) {
for (int i = 0; i < skinpath.length; i++) {
skin = getSkinInPath(skinpath[i], proto.getName(), skinname);
if (skin != null && skin.hasMainskin()) {
if (skin != null) {
// check if skin skin contains main skin
if (skin.hasMainskin()) {
return skin;
}
String extendz = skin.getExtends();
if (extendz != null && !extendz.equals(skinname)) {
return getSkin(prototype, extendz, skinpath);
}
} else if (parentName != null) {
// get parent skin
skin = getSkinInPath(skinpath[i], proto.getName(), parentName);
// check if it contains subskin
if (skin != null && skin.hasSubskin(subskinName)) {
if (skin != null) {
if (skin.hasSubskin(subskinName)) {
return skin.getSubskin(subskinName);
}
String extendz = skin.getExtends();
if (extendz != null && !extendz.equals(skinname)) {
return getSkin(prototype, extendz + "#" + subskinName, skinpath);
}
}
}
}
}