--[[ lama is a MUD server made in Lua. Copyright (C) 2013 Curtis Erickson This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. ]] --- Table that provides psuedo-inheritance-type features for tables. -- @author milkmanjack module("obj.Cloneable", package.seeall) --- Table that provides psuedo-inheritance-type features for tables.<br/><br/> -- Inheritance is achieved by using the __index metatable method, which just transfers attempts to index nil fields to the parent.<br/> -- <ul><li><b>Cloneable.clone(parent)</b> provides an interface for making a <i>pure clone</i> that is set to refer to the given parent.</li> -- <li><b>Cloneable.new(parent, ...)</b> provides an interface for making an <i>instance-style clone</i>, which has the properties of a <i>pure clone</i>, but is initialized.</li></ul> -- In effect, <i>pure clones</i> are meant to act as a <b>class</b> of a sort, and <i>instance-style clones</i> are meant to act as <b>instances of a class</b>. -- @class table -- @name Cloneable local Cloneable = {} --- Create a pure clone of a Cloneable. -- @param parent The parent to clone. Defaults to Cloneable. -- @return A pure clone of the parent. function Cloneable.clone(parent) local instance = {} setmetatable(instance, {__index=parent or Cloneable, __tostring=parent and parent.toString or Cloneable.toString } ) return instance end --- Creates an instance-style clone of a Cloneable. -- The clone is initialized, passing all arguments beyond the first to the clone's initialize() function. -- @param parent The parent to clone. Defaults to Cloneable. -- @param ... These arguments are passed to the clone's initialize() function. -- @return An instance-style clone of the parent. function Cloneable.new(parent, ...) local c = Cloneable.clone(parent) c:initialize(...) return c end --- Get the direct parent of the given Cloneable. -- @param clone The clone whose parent we want to check. -- @return The parent! function Cloneable.getParent(clone) if clone == Cloneable then return nil end local mt = getmetatable(clone) return mt.__index end --- Traverses a clone's parentage via their metatable's __index value. -- Determines whether or not this clone is a clone of another Cloneable. -- @param clone The Cloneable to check. -- @param ancestor The Cloneable we might be a clone of. -- @return true if given clone is a clone of given ancestor.<br/>false otherwise. function Cloneable.isCloneOf(clone, ancestor) local parent = clone:getParent() while parent do if parent == ancestor then return true end parent = parent:getParent() end return false end --- Constructor for instance-style clones. function Cloneable:initialize(...) end --- Stringifier for Cloneables. -- @return A string to identify this Cloneable. function Cloneable:toString() return "[cloneable]" end return Cloneable