define_implementations.h

Go to the documentation of this file.
00001 /*  
00002  *      define_implementations.h - macros for making implementation declarations
00003  *                                  for MAXscript functions
00004  *
00005  *  This will typically be used along with protocol definition files in 
00006  *  the Value subclasses that actually implement those protocols.
00007  *
00008  *  see define_abstract_functions.h for more info.
00009  *
00010  *  
00011  *  Copyright � John Wainwright 1996
00012  *
00013  */
00014 
00015 /* def_generic macro for implementation declaration in Value subclasses */
00016 
00017 #ifdef def_generic
00018 #   undef def_generic
00019 #   undef def_node_generic
00020 #   undef def_mapped_generic
00021 #   undef def_visible_generic
00022 #   undef def_struct_generic
00023 #   undef def_generic_debug_ok
00024 #   undef def_node_generic_debug_ok
00025 #   undef def_mapped_generic_debug_ok
00026 #   undef def_visible_generic_debug_ok
00027 #   undef def_struct_generic_debug_ok
00028 #   undef use_generic
00029 #   undef def_primitive
00030 #   undef def_mapped_primitive
00031 #   undef def_lazy_primitive
00032 #   undef def_visible_lazy_primitive
00033 #   undef def_visible_primitive
00034 #   undef def_struct_primitive
00035 #   undef def_primitive_debug_ok
00036 #   undef def_mapped_primitive_debug_ok
00037 #   undef def_lazy_primitive_debug_ok
00038 #   undef def_visible_lazy_primitive_debug_ok
00039 #   undef def_visible_primitive_debug_ok
00040 #   undef def_struct_primitive_debug_ok
00041 #   undef def_property
00042 #   undef def_property_alias
00043 #   undef def_2_prop_path
00044 #   undef def_2_prop_path_alias
00045 #   undef def_nested_prop
00046 #   undef def_nested_prop_alias
00047 #endif
00048 #ifdef def_prop_getter
00049 #   undef def_prop_getter
00050 #   undef def_prop_setter
00051 #endif
00052 
00053 #define def_generic(fn, name)   \
00054     Value* fn##_vf(Value** arglist, int arg_count)
00055 #define def_visible_generic(fn, name) def_generic(fn, name)
00056 #define def_struct_generic(fn, name) def_generic(fn, name)
00057 #define def_node_generic(fn, name) def_generic(fn, name)
00058 #define def_mapped_generic(fn, name) def_generic(fn, name)
00059 #define use_generic(fn, name) def_generic(fn, name)
00060 
00061 #define def_generic_debug_ok(fn, name) def_generic(fn, name)
00062 #define def_visible_generic_debug_ok(fn, name) def_generic(fn, name)
00063 #define def_struct_generic_debug_ok(fn, name) def_generic(fn, name)
00064 #define def_node_generic_debug_ok(fn, name) def_generic(fn, name)
00065 #define def_mapped_generic_debug_ok(fn, name) def_generic(fn, name)
00066 
00067 #define def_primitive(fn, name)     // nothing for implementation...
00068 #define def_lazy_primitive(fn, name) def_primitive(fn, name)
00069 #define def_visible_lazy_primitive(fn, name) def_primitive(fn, name)
00070 #define def_visible_primitive(fn, name) def_primitive(fn, name)
00071 #define def_mapped_primitive(fn, name) def_primitive(fn, name)
00072 #define def_struct_primitive(fn, _struct, name) def_primitive(fn, name)
00073 
00074 #define def_primitive_debug_ok(fn, name)        // nothing for implementation...
00075 #define def_visible_primitive_debug_ok(fn, name)
00076 #define def_mapped_primitive_debug_ok(fn, name)
00077 #define def_lazy_primitive_debug_ok(fn, name)
00078 #define def_visible_lazy_primitive_debug_ok(fn, name)
00079 #define def_struct_primitive_debug_ok(fn, _struct, name)
00080 
00081 #define def_property(p)                                     \
00082             Value*  get_##p(Value** arg_list, int count);   \
00083             Value*  set_##p(Value** arg_list, int count)
00084 #define def_prop_getter(p)                                  \
00085             Value*  get_##p(Value** arg_list, int count)
00086 #define def_prop_setter(p)                                  \
00087             Value*  set_##p(Value** arg_list, int count)
00088 #define def_property_alias(p, real_p)
00089 #define def_2_prop_path(p1, p2)                                     \
00090             Value*  get_##p1##_##p2(Value** arg_list, int count);   \
00091             Value*  set_##p1##_##p2(Value** arg_list, int count)
00092 #define def_2_prop_path_alias(p1, p2, real_p1, real_p2)
00093 #define def_nested_prop(p1)                                         \
00094             Value*  get_nested_##p1(Value** arg_list, int count);   \
00095             Value*  set_nested_##p1(Value** arg_list, int count)
00096 
00097 #define def_backpatched_setter(_prop, _superclass)                  \
00098             Value*                                                  \
00099             set_##_prop(Value** arg_list, int count)                \
00100             {                                                       \
00101                 _superclass::set_##_prop(arg_list, count);          \
00102                 back_patch();                                       \
00103                 return arg_list[0];                                 \
00104             };
00105 
00106 #define def_local_prop_alias(p, real_p)                                                             \
00107             Value*  get_##p(Value** arg_list, int count) { return get_##real_p(arg_list, count); }   \
00108             Value*  set_##p(Value** arg_list, int count) { return set_##real_p(arg_list, count); }   \
00109 
00110 #ifdef def_time_fn
00111 #   undef def_time_fn
00112 #endif
00113 #define def_time_fn(_fn)    \
00114     Value* _fn##_vf(Value** arglist, int arg_count)
00115 
00116 #undef def_name
00117 #define def_name(name)  n_##name = Name::intern(_M(#name));     
00118 
00119 #undef def_marker
00120 #define def_marker(var, str)
00121 
00122 /* ---------------------------- utility macros ---------------------*/
00123 
00124 #define _def_num_bin_op(_class, _conv, _op_fn, _op, _member)    \
00125     Value*                                                      \
00126     _class::_op_fn##_vf(Value** arg_list, int count)            \
00127     {                                                           \
00128         one_value_local(widened);                               \
00129         Value *arg, *result;                                    \
00130         arg = arg_list[0];                                      \
00131         if (tag != arg->tag && ((vl.widened = widen_to(arg, arg_list)) != NULL))    \
00132             result = vl.widened->_op_fn##_vf(arg_list, 1);      \
00133         else                                                    \
00134             result = _class::intern(_member _op (arg_list[0])->_conv()); \
00135         pop_value_locals();                                     \
00136         return result;                                          \
00137     }
00138 
00139 #define _def_bin_op(_class, _conv, _op_fn, _op, _member)        \
00140     Value*                                                      \
00141     _class::_op_fn##_vf(Value** arg_list, int count)            \
00142     {                                                           \
00143         one_value_local(widened);                               \
00144         Value *arg, *result;                                    \
00145         arg = arg_list[0];                                      \
00146         if (tag != arg->tag && ((vl.widened = widen_to(arg, arg_list)) != NULL))    \
00147             result = vl.widened->_op_fn##_vf(arg_list, 1);      \
00148         else                                                    \
00149             result = new _class (_member _op (arg_list[0])->_conv()); \
00150         pop_value_locals();                                     \
00151         return result;                                          \
00152     }
00153 
00154 #define _def_rel_op(_class, _conv, _op_fn, _rel_op, _member)    \
00155     Value*                                                      \
00156     _class::_op_fn##_vf(Value** arg_list, int count)            \
00157     {                                                           \
00158         Value *cmpnd = arg_list[0], *result;                    \
00159         if (comparable(cmpnd))                                  \
00160             result = (_member _rel_op cmpnd->_conv()) ?         \
00161                         &true_value : &false_value;             \
00162         else                                                    \
00163             throw IncompatibleTypes(this, cmpnd);               \
00164         return result;                                          \
00165     }
00166 
00167 #define def_eq_op(_class, comparison_method, _member)           \
00168     Value*                                                      \
00169     _class::eq_vf(Value** arg_list, int count)                  \
00170     {                                                           \
00171         Value* cmpnd = arg_list[0];                             \
00172         Value* result;                                          \
00173         if (comparable(cmpnd))                                  \
00174             result = (_member == cmpnd->comparison_method()) ?  \
00175                 &true_value : &false_value;                     \
00176         else                                                    \
00177             result = &false_value;                              \
00178         return result;                                          \
00179     }
00180 
00181 #define def_ne_op(_class, comparison_method, _member)           \
00182     Value*                                                      \
00183     _class::ne_vf(Value** arg_list, int count)                  \
00184     {                                                           \
00185         Value* cmpnd = arg_list[0];                             \
00186         Value* result;                                          \
00187         if (comparable(cmpnd))                                  \
00188             result = (_member == cmpnd->comparison_method()) ?  \
00189                         &false_value : &true_value;             \
00190         else                                                    \
00191             result = &true_value;                               \
00192         return result;                                          \
00193     }
00194 
00195 
00196 #define _def_num_un_op(_class, _op_fn, _op, _member)            \
00197     Value*                                                      \
00198     _class::_op_fn##_vf(Value** arg_list, int count)            \
00199     {                                                           \
00200         return _class::intern(_op _member);                     \
00201     }
00202 
00203 #define _def_un_op(_class, _op_fn, _op, _member)                \
00204     Value*                                                      \
00205     _class::_op_fn##_vf(Value** arg_list, int count)            \
00206     {                                                           \
00207         return new _class (_op _member);                        \
00208     }
00209 
00210 #define def_bin_op(_class, _conv, _op_fn, _op)                  \
00211             _def_num_bin_op(_class, _conv, _op_fn, _op, value)
00212 #define def_rel_op(_class, _conv, _op_fn, _rel_op)              \
00213             _def_rel_op(_class, _conv, _op_fn, _rel_op, value)
00214 #define def_un_op(_class, _op_fn, _op)                          \
00215             _def_num_un_op(_class, _op_fn, _op, value)
00216 
00217 #define PI_double     (3.14159265358979323846)
00218 #define TWOPI_double  (6.28318530717958647652)
00219 #define HALFPI_double (1.57079632679489661973)
00220 
00221 #define DEG_TO_RAD_double (PI_double/180.0)
00222 #define RAD_TO_DEG_double (180.0/PI_double)
00223 #define DegToRad_double(deg) (((double)deg)*DEG_TO_RAD_double)
00224 #define RadToDeg_double(rad) (((double)rad)*RAD_TO_DEG_double)
00225 
00226 #define DegToRad_float(deg) DegToRad(deg)
00227 #define RadToDeg_float(rad) RadToDeg(rad)
00228 
00229 #define def_math_fn(_class, _outclass, _type, _conv, _fn)           \
00230     Value*                                              \
00231     _class::_fn##_vf(Value** arg_list, int count)       \
00232     {                                                   \
00233         check_arg_count(_fn, 1, count+1);               \
00234         return _outclass::intern((_type)_fn(_conv()));      \
00235     }
00236 
00237 #define def_angle_trig_fn(_class, _outclass, _type, _conv, _fn)             \
00238     Value*                                                          \
00239     _class::_fn##_vf(Value** arg_list, int count)                   \
00240     {                                                               \
00241         check_arg_count(_fn, 1, count+1);                           \
00242         return _outclass::intern(RadToDeg_##_type((_type)_fn(_conv()))); \
00243     }
00244 
00245 #define def_float_trig_fn(_class, _outclass, _type, _conv, _fn)             \
00246     Value*                                                          \
00247     _class::_fn##_vf(Value** arg_list, int count)                   \
00248     {                                                               \
00249         check_arg_count(_fn, 1, count+1);                           \
00250         return _outclass::intern((_type)_fn(DegToRad_##_type(_conv()))); \
00251     }
00252 
00253 #define def_math_bin_fn(_class, _outclass, _type, _conv, _fn)               \
00254     Value*                                                      \
00255     _class::_fn##_vf(Value** arg_list, int count)               \
00256     {                                                           \
00257         check_arg_count(_fn, 2, count+1);                       \
00258         return _outclass::intern((_type)_fn(_conv(),                \
00259                               arg_list[0]->_conv()));           \
00260     }
00261 
00262 #define def_angle_trig_bin_fn(_class, _outclass, _type, _conv, _fn)         \
00263     Value*                                                          \
00264     _class::_fn##_vf(Value** arg_list, int count)                   \
00265     {                                                               \
00266         check_arg_count(_fn, 2, count+1);                           \
00267         return _outclass::intern(RadToDeg_##_type((_type)_fn(_conv(),   \
00268                               arg_list[0]->_conv())));              \
00269     }
00270 
00271 #define def_num_prop_accessors(_class, _prop, _member, _type, _conv ) \
00272     Value*                                                          \
00273     _class::get_##_prop(Value** arg_list, int count)                \
00274     {                                                               \
00275         return _type::intern(_member);                              \
00276     }                                                               \
00277     Value*                                                          \
00278     _class::set_##_prop(Value** arg_list, int count)                \
00279     {                                                               \
00280         Value*  val = arg_list[0];                                  \
00281         _member = val->_conv();                                     \
00282         return val;                                                 \
00283     }
00284 
00285 #define def_prop_accessors(_class, _prop, _member, _type, _conv )   \
00286     Value*                                                          \
00287     _class::get_##_prop(Value** arg_list, int count)                \
00288     {                                                               \
00289         return new _type (_member);                                 \
00290     }                                                               \
00291     Value*                                                          \
00292     _class::set_##_prop(Value** arg_list, int count)                \
00293     {                                                               \
00294         Value*  val = arg_list[0];                                  \
00295         _member = val->_conv();                                     \
00296         return val;                                                 \
00297     }
00298 
00299 #define def_fn_prop_accessors(_class, _prop, _getter, _setter)      \
00300     Value*                                                          \
00301     _class::get_##_prop(Value** arg_list, int count)                \
00302     {                                                               \
00303         return _getter;                                             \
00304     }                                                               \
00305     Value*                                                          \
00306     _class::set_##_prop(Value** arg_list, int count)                \
00307     {                                                               \
00308         Value*  val = arg_list[0];                                  \
00309         _setter;                                                    \
00310         return val;                                                 \
00311     }
00312 
00313 #define def_fn_prop_getter(_class, _prop, _getter)                  \
00314     Value*                                                          \
00315     _class::get_##_prop(Value** arg_list, int count)                \
00316     {                                                               \
00317         return _getter;                                             \
00318     }                                                               
00319 
00320 #define def_fn_prop_setter(_class, _prop, _setter)                  \
00321     Value*                                                          \
00322     _class::set_##_prop(Value** arg_list, int count)                \
00323     {                                                               \
00324         Value*  val = arg_list[0];                                  \
00325         _setter;                                                    \
00326         return val;                                                 \
00327     }
00328 
00329 #define def_float_prop_accessors(_class, _prop, _member)                \
00330             def_num_prop_accessors(_class, _prop, _member, Float, to_float)
00331 
00332 #define def_int_prop_accessors(_class, _prop, _member)                  \
00333             def_num_prop_accessors(_class, _prop, _member, Integer, to_int)
00334 
00335 #define def_point3_prop_accessors(_class, _prop, _member)               \
00336             def_fn_prop_accessors(_class, _prop, new Point3Value (_member), _member = val->to_point3())
00337 
00338 #define def_angle_prop_accessors(_class, _prop, _member)                \
00339             def_fn_prop_accessors(_class, _prop, Float::intern(RadToDeg(_member)), _member = DegToRad(val->to_float()))
00340 
00341 #define def_time_bin_op(_op_fn, _op)                            \
00342             _def_bin_op(MSTime, to_timevalue, _op_fn, _op, time)
00343 #define def_time_rel_op(_op_fn, _rel_op)                        \
00344             _def_rel_op(MSTime, to_timevalue, _op_fn, _rel_op, time)
00345 #define def_time_un_op(_op_fn, _op)                             \
00346             _def_un_op(MSTime, _op_fn, _op, time)
00347 
00348 #define def_quat_bin_op(_class, _conv, _op_fn, _op)             \
00349             _def_bin_op(_class, _conv, _op_fn, _op, q)
00350 #define def_quat_rel_op(_class, _conv, _op_fn, _rel_op)         \
00351             _def_rel_op(_class, _conv, _op_fn, _rel_op, q)
00352 #define def_quat_un_op(_class, _op_fn, _op)                     \
00353             _def_un_op(_class, _op_fn, _op, q)
00354                 
00355 #define def_new_quat_fn(_fn, _arg_count, _call)             \
00356     Value*                                                  \
00357     QuatValue::_fn##_vf(Value** arg_list, int count)        \
00358     {                                                       \
00359         check_arg_count(_fn, _arg_count, count + 1);        \
00360         return new QuatValue (_call);                       \
00361     }
00362 
00363 #define def_mut_quat_fn(_fn, _arg_count, _call)             \
00364     Value*                                                  \
00365     QuatValue::_fn##_vf(Value** arg_list, int count)        \
00366     {                                                       \
00367         check_arg_count(_fn, _arg_count, count + 1);        \
00368         _call;                                              \
00369         return this;                                        \
00370     }
00371 
00372 #define def_new_mat_fn(_fn, _arg_count, _call)              \
00373     Value*                                                  \
00374     Matrix3Value::_fn##_vf(Value** arg_list, int count)     \
00375     {                                                       \
00376         check_arg_count(_fn, _arg_count, count + 1);        \
00377         return new Matrix3Value (_call);                        \
00378     }
00379 
00380 #define def_mut_mat_fn(_fn, _arg_count, _call)              \
00381     Value*                                                  \
00382     Matrix3Value::_fn##_vf(Value** arg_list, int count)     \
00383     {                                                       \
00384         check_arg_count(_fn, _arg_count, count + 1);        \
00385         _call;                                              \
00386         return this;                                        \
00387     }
00388 
00389 #define def_mat_primitive(_fn, _arg_count, _call)           \
00390     Value*                                                  \
00391     _fn##_cf(Value** arg_list, int count)                   \
00392     {                                                       \
00393         check_arg_count(_fn, _arg_count, count);            \
00394         return new Matrix3Value (_call);                    \
00395     }
00396 
00397 #define def_mat_bin_op(_class, _conv, _op_fn, _op)          \
00398             _def_bin_op(_class, _conv, _op_fn, _op, m)
00399 #define def_mat_rel_op(_class, _conv, _op_fn, _rel_op)      \
00400             _def_rel_op(_class, _conv, _op_fn, _rel_op, m)
00401 #define def_mat_un_op(_class, _op_fn, _op)                  \
00402             _def_un_op(_class, _op_fn, _op, m)
00403                 
00404 // LAM: 2/27/01 - modified following to invalidate foreground/background rectangle instead of just 
00405 // foreground
00406 
00407 #define def_bool_node_fns(name, getter, setter)                                                 \
00408     Value* node_get_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Interval& valid)     \
00409     {                                                                                           \
00410         return ((INode*)obj)->getter() ? &true_value : &false_value;                            \
00411     }                                                                                           \
00412     void node_set_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Value* val)            \
00413     {                                                                                           \
00414         ((INode*)obj)->setter(val->to_bool());                                                  \
00415         InvalidateNodeRect((INode*)obj,t);                                                      \
00416     }
00417 
00418 #define def_bool_node_getter(name, getter)                                                      \
00419     Value* node_get_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Interval& valid)     \
00420     {                                                                                           \
00421         return ((INode*)obj)->getter() ? &true_value : &false_value;                            \
00422     }                                                                                           \
00423     void node_set_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Value* val)            \
00424     {                                                                                           \
00425         throw RuntimeError (_M("Property not settable: "), #name);                              \
00426     }
00427                                                                                             
00428 #define def_ulong_node_fns(name, getter, setter)                                                \
00429     Value* node_get_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Interval& valid)     \
00430     {                                                                                           \
00431         return Integer::intern((int)((INode*)obj)->getter());                                   \
00432     }                                                                                           \
00433     void node_set_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Value* val)            \
00434     {                                                                                           \
00435         ((INode*)obj)->setter((ULONG)val->to_int());                                            \
00436         InvalidateNodeRect((INode*)obj,t);                                                      \
00437     }
00438 
00439 #define def_color_node_fns(name, getter, setter)                                                \
00440     Value* node_get_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Interval& valid)     \
00441     {                                                                                           \
00442         DWORD rgb = ((INode*)obj)->getter();                                                    \
00443         return ColorValue::intern(GetRValue(rgb) / 255.0f, GetGValue(rgb) / 255.0f, GetBValue(rgb) / 255.0f);   \
00444     }                                                                                           \
00445     void node_set_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Value* val)            \
00446     {                                                                                           \
00447         AColor c;                                                                               \
00448         c = val->to_acolor();                                                                   \
00449         ((INode*)obj)->setter(RGB((BYTE)(c.r * 255), (BYTE)(c.g * 255), (BYTE)(c.b * 255)));    \
00450         InvalidateNodeRect((INode*)obj,t);                                                      \
00451     }
00452 
00453 // LAM: 2/27/01 - use following for node properties that don't require a redraw
00454 
00455 // The following defines has been added
00456 // in 3ds max 4.2.  If your plugin utilizes this new
00457 // mechanism, be sure that your clients are aware that they
00458 // must run your plugin with 3ds max version 4.2 or higher.
00459 
00460 #define def_bool_node_noredraw_fns(name, getter, setter)                                                    \
00461     Value* node_get_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Interval& valid)     \
00462     {                                                                                           \
00463         return ((INode*)obj)->getter() ? &true_value : &false_value;                            \
00464     }                                                                                           \
00465     void node_set_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Value* val)            \
00466     {                                                                                           \
00467         ((INode*)obj)->setter(val->to_bool());                                                  \
00468     }
00469 
00470 #define def_ulong_node_noredraw_fns(name, getter, setter)                                               \
00471     Value* node_get_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Interval& valid)     \
00472     {                                                                                           \
00473         return Integer::intern((int)((INode*)obj)->getter());                                   \
00474     }                                                                                           \
00475     void node_set_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Value* val)            \
00476     {                                                                                           \
00477         ((INode*)obj)->setter((ULONG)val->to_int());                                            \
00478     }
00479 
00480 #define def_color_node_noredraw_fns(name, getter, setter)                                               \
00481     Value* node_get_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Interval& valid)     \
00482     {                                                                                           \
00483         DWORD rgb = ((INode*)obj)->getter();                                                    \
00484         return ColorValue::intern(GetRValue(rgb) / 255.0f, GetGValue(rgb) / 255.0f, GetBValue(rgb) / 255.0f);   \
00485     }                                                                                           \
00486     void node_set_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Value* val)            \
00487     {                                                                                           \
00488         AColor c;                                                                               \
00489         c = val->to_acolor();                                                                   \
00490         ((INode*)obj)->setter(RGB((BYTE)(c.r * 255), (BYTE)(c.g * 255), (BYTE)(c.b * 255)));    \
00491     }
00492 
00493 // End of 3ds max 4.2 Extension