define_abstract_functions.h

Go to the documentation of this file.
00001 /*  
00002  *      def_abstract_functions.h - macros for making abstract declarations for MAXScript functions
00003  *
00004  *  This will typically be used along with protocol definition files in Value.h
00005  *  to declare all the possible scripter-visible operations on MAXScript values.
00006  *
00007  *  MAXScript generics are scripter-visible first-class values that wrap a
00008  *  reference to a virtual function declared on class Value.  All core generics
00009  *  are defined this way via a set of defining macros and protocol files for
00010  *  each suite of operations.  The core generics are all globally declared
00011  *  Generic instances, with names of the form xxx_gf. Corresponding virtuals
00012  *  are declared abstractly in class Value and have names of the form xxx_vf.
00013  *
00014  *  All thusly declared genrics have the same signature:  
00015  *          Value* xxx_vf(Value** arglist, int arg_count);
00016  *  That is, they are polymorphic up to Values and take an argument list array &
00017  *  actual count which they should check for conformance at runtime.
00018  *
00019  *  Value subclasses that implement a particular protocol should use 
00020  *  def_implement_generics.h macros to declare implementations.  And one
00021  *  of these classes should use def_instance_generics.h to actually globally
00022  *  instantiate the generic objects.  The abstract declarations in Value
00023  *  all contain type error signals, so that any generic invoked on a
00024  *  Value subclass instance that doesn't implement the generic will
00025  *  get a runtime type error.
00026  *
00027  *  Similarly, scripter-visible primitive functions (non-generic) are 
00028  *  represented by instances of the Primitive class and declared using
00029  *  these same def macro headers & corresponding def_primitive macros.
00030  *  
00031  *  Copyright � John Wainwright 1996
00032  *
00033  */
00034 
00035 /* def_generic macro for abstract declaration in Value class */
00036 
00037 #ifdef def_generic
00038 #   undef def_generic
00039 #   undef def_node_generic
00040 #   undef def_mapped_generic
00041 #   undef def_visible_generic
00042 #   undef def_struct_generic
00043 #   undef def_generic_debug_ok
00044 #   undef def_node_generic_debug_ok
00045 #   undef def_mapped_generic_debug_ok
00046 #   undef def_visible_generic_debug_ok
00047 #   undef def_struct_generic_debug_ok
00048 #   undef use_generic
00049 #   undef def_primitive
00050 #   undef def_mapped_primitive
00051 #   undef def_lazy_primitive
00052 #   undef def_visible_lazy_primitive
00053 #   undef def_visible_primitive
00054 #   undef def_struct_primitive
00055 #   undef def_primitive_debug_ok
00056 #   undef def_mapped_primitive_debug_ok
00057 #   undef def_lazy_primitive_debug_ok
00058 #   undef def_visible_lazy_primitive_debug_ok
00059 #   undef def_visible_primitive_debug_ok
00060 #   undef def_struct_primitive_debug_ok
00061 #   undef def_property
00062 #   undef def_property_alias
00063 #   undef def_2_prop_path
00064 #   undef def_2_prop_path_alias
00065 #   undef def_nested_prop
00066 #   undef def_nested_prop_alias
00067 #endif
00068 #ifdef def_prop_getter
00069 #   undef def_prop_getter
00070 #   undef def_prop_setter
00071 #endif
00072 
00073 #define def_generic(fn, name)   \
00074     virtual Value* fn##_vf(Value** arglist, int arg_count) { ABSTRACT_FUNCTION(_M(#name), this, Value*); }
00075 #define def_visible_generic(fn, name) def_generic(fn, name)
00076 #define def_struct_generic(fn, name) def_generic(fn, name)
00077 #define def_node_generic(fn, name) def_generic(fn, name)
00078 #define def_mapped_generic(fn, name) def_generic(fn, name)
00079 #define use_generic(fn, name)
00080 
00081 #define def_generic_debug_ok(fn, name) def_generic(fn, name)
00082 #define def_visible_generic_debug_ok(fn, name) def_generic(fn, name)
00083 #define def_struct_generic_debug_ok(fn, name) def_generic(fn, name)
00084 #define def_node_generic_debug_ok(fn, name) def_generic(fn, name)
00085 #define def_mapped_generic_debug_ok(fn, name) def_generic(fn, name)
00086 
00087 #define def_primitive(fn, name)     // no member function declarations for primitives
00088 #define def_visible_primitive(fn, name)
00089 #define def_mapped_primitive(fn, name)
00090 #define def_lazy_primitive(fn, name)
00091 #define def_visible_lazy_primitive(fn, name)
00092 #define def_struct_primitive(fn, _struct, name)
00093 
00094 #define def_primitive_debug_ok(fn, name)        // no member function declarations for primitives
00095 #define def_visible_primitive_debug_ok(fn, name)
00096 #define def_mapped_primitive_debug_ok(fn, name)
00097 #define def_lazy_primitive_debug_ok(fn, name)
00098 #define def_visible_lazy_primitive_debug_ok(fn, name)
00099 #define def_struct_primitive_debug_ok(fn, _struct, name)
00100 
00101 #define def_property(p)                                                                                     \
00102             virtual Value*  get_##p(Value** arg_list, int count) { return get_property(arg_list, count); }  \
00103             virtual Value*  set_##p(Value** arg_list, int count) { return set_property(arg_list, count); }  
00104 #define def_property_alias(p, real_p)
00105 #define def_2_prop_path(p1, p2)                                             \
00106             virtual Value*  get_##p1##_##p2(Value** arg_list, int count)    \
00107             {                                                               \
00108                 two_value_locals(cont, result);                             \
00109                 vl.cont = get_##p1(&n_##p1, 1);                             \
00110                 vl.result = vl.cont->get_##p2(&n_##p2, 1);                  \
00111                 return_value(vl.result);                                    \
00112             }                                                               \
00113             virtual Value*  set_##p1##_##p2(Value** arg_list, int count)    \
00114             {                                                               \
00115                 one_value_local(cont);                                      \
00116                 Value* args[2] = { arg_list[0], n_##p2 };                   \
00117                 vl.cont = get_##p1(&n_##p1, 1);                             \
00118                 vl.cont->set_##p2(args, 2);                                 \
00119                 args[0] = vl.cont; args[1] = n_##p1;                        \
00120                 set_##p1(args, 2);                                          \
00121                 pop_value_locals();                                         \
00122                 return arg_list[0];                                         \
00123             }
00124 #define def_2_prop_path_alias(p1, p2, real_p1, real_p2)
00125 #define def_nested_prop(p1)                                                 \
00126             virtual Value*  get_nested_##p1(Value** arg_list, int count)    \
00127             {                                                               \
00128                 two_value_locals(cont, result);                             \
00129                 vl.cont = _get_property(arg_list[0]);                       \
00130                 vl.result = vl.cont->get_##p1(&n_##p1, 1);                  \
00131                 return_value(vl.result);                                    \
00132             }                                                               \
00133             virtual Value*  set_nested_##p1(Value** arg_list, int count)    \
00134             {                                                               \
00135                 one_value_local(cont);                                      \
00136                 Value* args[2] = { arg_list[0], n_##p1 };                   \
00137                 vl.cont = _get_property(arg_list[1]);                       \
00138                 vl.cont->set_##p1(args, 2);                                 \
00139                 _set_property(arg_list[1], vl.cont);                        \
00140                 pop_value_locals();                                         \
00141                 return arg_list[0];                                         \
00142             }
00143 
00144 #define def_nested_prop_alias(p1, real_p1)                                  
00145 
00146 /* abstract function 'bodies'... if these are called, we have a 'type doesnt implement' error  */
00147 
00148 #define ABSTRACT_FUNCTION(m, v, t) throw NoMethodError (m, v); return (t)0        
00149 #define ABSTRACT_CONVERTER(t, l) throw ConversionError (this, _M(#l)); return (t)0
00150 #define ABSTRACT_WIDENER(a) throw IncompatibleTypes (this, a); return (Value*)&undefined
00151 #define ABSTRACT_GETTER() throw AccessorError (this, arg_list[0]); return (Value*)&undefined
00152 #define ABSTRACT_SETTER() throw AccessorError (this, arg_list[1]); return (Value*)&undefined
00153