+ if (layer < 0 || layer >= (int)layers.size())
+ throw BaseException("Invalid settings layer");
+ return layers[layer];
+}
+
+
+Settings *SettingsHierarchy::getParent(int layer) const
+{
+ assert(layer >= 0 && layer < (int)layers.size());
+ // iterate towards the origin (0) to find the next fallback layer
+ for (int i = layer - 1; i >= 0; --i) {
+ if (layers[i])
+ return layers[i];
+ }
+
+ return nullptr;
+}
+
+
+void SettingsHierarchy::onLayerCreated(int layer, Settings *obj)
+{
+ if (layer < 0)
+ throw BaseException("Invalid settings layer");
+ if ((int)layers.size() < layer + 1)
+ layers.resize(layer + 1);
+
+ Settings *&pos = layers[layer];
+ if (pos)
+ throw BaseException("Setting layer " + itos(layer) + " already exists");
+
+ pos = obj;
+ // This feels bad
+ if (this == &g_hierarchy && layer == (int)SL_GLOBAL)
+ g_settings = obj;
+}
+
+
+void SettingsHierarchy::onLayerRemoved(int layer)
+{
+ assert(layer >= 0 && layer < (int)layers.size());
+ layers[layer] = nullptr;
+ if (this == &g_hierarchy && layer == (int)SL_GLOBAL)
+ g_settings = nullptr;
+}
+
+/* Settings implementation */
+
+Settings *Settings::createLayer(SettingsLayer sl, const std::string &end_tag)
+{
+ return new Settings(end_tag, &g_hierarchy, (int)sl);
+}
+
+
+Settings *Settings::getLayer(SettingsLayer sl)
+{
+ return g_hierarchy.getLayer(sl);
+}
+
+
+Settings::Settings(const std::string &end_tag, SettingsHierarchy *h,
+ int settings_layer) :
+ m_end_tag(end_tag),
+ m_hierarchy(h),
+ m_settingslayer(settings_layer)
+{
+ if (m_hierarchy)
+ m_hierarchy->onLayerCreated(m_settingslayer, this);
+}
+