1 /* Copyright (C) 2000-2005 Thomas Bopp, Thorsten Hampel, Ludger Merkens
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 * $Id: decorateable.pike,v 1.1 2008/03/31 13:39:57 exodusd Exp $
20 #include <exception.h>
25 #include <attributes.h>
26 //! The decoration features of a sTeam object are implemented in this file.
27 //! Object uses it so any object inside a sTeam server features a list
28 //! of decorations. The functions to add and remove decorations are located
29 //! in Object and call the low level functions in this class.
37 array aDecorations; // list of decorations
39 string get_identifier();
41 void require_save(void|string ident, void|string index);
44 * Initialization of decorations on this object.
47 * @see remove_decoration
50 void init_decorations()
58 * Add a decoration to this object. The decoration is identified by a path of
59 * the form: "server:/path-in-server-sandbox" or "object:/object-path" or
60 * "object:#object-id". An instance of the decoration will be provided and
61 * attached to the proxy of this object.
63 * @param string path the path to the decoration source code
64 * @return true if the decoration could be successfully added, false if not
65 * @see remove_decoration
68 bool add_decoration ( string path )
70 if ( !stringp(path) || path == "" )
71 THROW( "Trying to add decoration with empty path !", E_ERROR );
72 LOG( "Adding decoration: " + path + " to "+ get_identifier() );
73 return do_add_decoration( path );
79 bool do_add_decoration ( string path )
81 if ( search( aDecorations, path ) >= 0 )
82 steam_error( "add_decoration: Decoration already on %O\n", get_identifier() );
84 aDecorations += ({ path });
86 require_save( STORE_DECORATIONS );
93 object load_decoration ( string path )
95 string type, decoration_path, decorator_content;
97 if ( ! stringp(path) )
98 steam_error( "No decoration given!\n" );
100 if (sscanf(path, "%s:%s", type, decoration_path) != 2) {
101 decoration_path = path;
105 if ( !stringp(decoration_path) || decoration_path == "" )
106 steam_error( "No decoration given!\n" );
108 switch ( lower_case( type ) ) {
111 string sandbox_path = _Server->get_sandbox_path();
112 decorator_content = Stdio.read_file( sandbox_path + decoration_path );
113 if ( !stringp(decorator_content) )
114 steam_error( "Failed to find decoration object in server dir (%s):" +
115 " %s\n", sandbox_path, decoration_path );
121 if ( decoration_path[0] == '#' ) {
122 int id = (int)(decoration_path[1..]);
123 object co = find_object( id );
125 steam_error( "Failed to find decoration object with id %d\n", id );
126 decorator_content = co->get_content();
129 object co = OBJ( decoration_path );
131 steam_error( "Failed to find decoration object in %s\n",
133 decorator_content = co->get_content();
138 if ( !stringp(decorator_content) || sizeof(decorator_content) == 0 )
139 steam_error( "Decoration has no content: %s\n", path );
142 mixed err = catch( p = compile_string( decorator_content ) );
144 werror( "Failed to compile decoration: %s\n", path );
148 if ( ! Program.implements( p, pApi ) )
149 steam_error( "Decoration program does not implement decoration api, " +
150 "should implement get_decoration_class() !\n" );
153 if ( objectp(decoration_obj) )
154 return decoration_obj;
161 * Removes a decoration from the object. This function just removes
162 * the decoration path from the list of decorations.
164 * @param string path the decoration path to remove
165 * @return true if the decoration was successfully removed, false otherwise
166 * @see add_decoration
169 bool remove_decoration ( string path )
171 if ( search( aDecorations, path ) == -1 )
172 THROW( "Decoration " + path + " not present on object !", E_ERROR );
174 aDecorations -= ({ path });
176 require_save( STORE_DECORATIONS );
183 * This function returns a copied list of all decorations of this
186 * @return the array of decorations
188 array get_decorations ()
190 return copy_value( aDecorations );
194 * Checks whether this object has a certain decoration.
196 * @param path the decoration path
197 * @return true if the object has this decoration, false if not
199 bool has_decoration ( string path )
201 return search( aDecorations, path ) >= 0;
205 * Retrieve decorations for storing them in the database.
206 * Only the global _Database object is able to call this function.
208 * @return mapping of object data.
210 * @see restore_decorations
213 final mapping retrieve_decorations ()
215 if ( CALLER != _Database )
216 THROW( "Caller is not the database object !", E_ACCESS );
218 return ([ "Decorations" : aDecorations ]);
224 * Called by database to restore the object data again upon loading.
226 * @param mixed the object data
228 * @see retrieve_decorations
231 final void restore_decorations ( mixed data )
233 if ( CALLER != _Database )
234 THROW( "Caller is not the database object !", E_ACCESS );
236 aDecorations = data[ "Decorations" ];
237 if ( !arrayp(aDecorations) ) {
238 aDecorations = ({ });
239 require_save( STORE_DECORATIONS );