/* * def_implement_functions.h - macros for making implementation declarations * for MAXscript functions * * This will typically be used along with protocol definition files in * the Value subclasses that actually implement those protocols. * * see def_abstract_functionss.h for more info. * * * Copyright © John Wainwright 1996 * */ /* def_generic macro for implementation declaration in Value subclasses */ #ifdef def_generic # undef def_generic # undef def_node_generic # undef def_mapped_generic # undef def_visible_generic # undef def_struct_generic # undef use_generic # undef def_primitive # undef def_mapped_primitive # undef def_lazy_primitive # undef def_visible_lazy_primitive # undef def_visible_primitive # undef def_struct_primitive # undef def_property # undef def_property_alias # undef def_2_prop_path # undef def_2_prop_path_alias # undef def_nested_prop # undef def_nested_prop_alias #endif #ifdef def_prop_getter # undef def_prop_getter # undef def_prop_setter #endif #define def_generic(fn, name) \ Value* fn##_vf(Value** arglist, int arg_count) #define def_visible_generic(fn, name) def_generic(fn, name) #define def_struct_generic(fn, name) def_generic(fn, name) #define def_node_generic(fn, name) def_generic(fn, name) #define def_mapped_generic(fn, name) def_generic(fn, name) #define use_generic(fn, name) def_generic(fn, name) #define def_primitive(fn, name) // nothing for implementation... #define def_lazy_primitive(fn, name) def_primitive(fn, name) #define def_visible_lazy_primitive(fn, name) def_primitive(fn, name) #define def_visible_primitive(fn, name) def_primitive(fn, name) #define def_mapped_primitive(fn, name) def_primitive(fn, name) #define def_struct_primitive(fn, _struct, name) def_primitive(fn, name) #define def_property(p) \ Value* get_##p(Value** arg_list, int count); \ Value* set_##p(Value** arg_list, int count) #define def_prop_getter(p) \ Value* get_##p(Value** arg_list, int count) #define def_prop_setter(p) \ Value* set_##p(Value** arg_list, int count) #define def_property_alias(p, real_p) #define def_2_prop_path(p1, p2) \ Value* get_##p1##_##p2(Value** arg_list, int count); \ Value* set_##p1##_##p2(Value** arg_list, int count) #define def_2_prop_path_alias(p1, p2, real_p1, real_p2) #define def_nested_prop(p1) \ Value* get_nested_##p1(Value** arg_list, int count); \ Value* set_nested_##p1(Value** arg_list, int count) #define def_backpatched_setter(_prop, _superclass) \ Value* \ set_##_prop(Value** arg_list, int count) \ { \ _superclass::set_##_prop(arg_list, count); \ back_patch(); \ return arg_list[0]; \ }; #define def_local_prop_alias(p, real_p) \ Value* get_##p(Value** arg_list, int count) { return get_##real_p(arg_list, count); } \ Value* set_##p(Value** arg_list, int count) { return set_##real_p(arg_list, count); } \ #ifdef def_time_fn # undef def_time_fn #endif #define def_time_fn(_fn) \ Value* _fn##_vf(Value** arglist, int arg_count) #undef def_name #define def_name(name) n_##name = Name::intern(_T(#name)); #undef def_marker #define def_marker(var, str) /* ---------------------------- utility macros ---------------------*/ #define _def_num_bin_op(_class, _conv, _op_fn, _op, _member) \ Value* \ _class::_op_fn##_vf(Value** arg_list, int count) \ { \ one_value_local(widened); \ Value *arg, *result; \ arg = arg_list[0]; \ if (tag != arg->tag && (vl.widened = widen_to(arg, arg_list))) \ result = vl.widened->_op_fn##_vf(arg_list, 1); \ else \ result = _class::intern(_member _op (arg_list[0])->_conv()); \ pop_value_locals(); \ return result; \ } #define _def_bin_op(_class, _conv, _op_fn, _op, _member) \ Value* \ _class::_op_fn##_vf(Value** arg_list, int count) \ { \ one_value_local(widened); \ Value *arg, *result; \ arg = arg_list[0]; \ if (tag != arg->tag && (vl.widened = widen_to(arg, arg_list))) \ result = vl.widened->_op_fn##_vf(arg_list, 1); \ else \ result = new _class (_member _op (arg_list[0])->_conv()); \ pop_value_locals(); \ return result; \ } #define _def_rel_op(_class, _conv, _op_fn, _rel_op, _member) \ Value* \ _class::_op_fn##_vf(Value** arg_list, int count) \ { \ Value *cmpnd = arg_list[0], *result; \ if (comparable(cmpnd)) \ result = (_member _rel_op cmpnd->_conv()) ? \ &true_value : &false_value; \ else \ throw IncompatibleTypes(this, cmpnd); \ return result; \ } #define def_eq_op(_class, _conv, _member) \ Value* \ _class::eq_vf(Value** arg_list, int count) \ { \ Value *cmpnd = arg_list[0], *result; \ if (comparable(cmpnd)) \ result = (_member == cmpnd->_conv()) ? \ &true_value : &false_value; \ else \ result = &false_value; \ return result; \ } #define def_ne_op(_class, _conv, _member) \ Value* \ _class::ne_vf(Value** arg_list, int count) \ { \ Value *cmpnd = arg_list[0], *result; \ if (comparable(cmpnd)) \ result = (_member == cmpnd->_conv()) ? \ &false_value : &true_value; \ else \ result = &true_value; \ return result; \ } #define _def_num_un_op(_class, _op_fn, _op, _member) \ Value* \ _class::_op_fn##_vf(Value** arg_list, int count) \ { \ return _class::intern(_op _member); \ } #define _def_un_op(_class, _op_fn, _op, _member) \ Value* \ _class::_op_fn##_vf(Value** arg_list, int count) \ { \ return new _class (_op _member); \ } #define def_bin_op(_class, _conv, _op_fn, _op) \ _def_num_bin_op(_class, _conv, _op_fn, _op, value) #define def_rel_op(_class, _conv, _op_fn, _rel_op) \ _def_rel_op(_class, _conv, _op_fn, _rel_op, value) #define def_un_op(_class, _op_fn, _op) \ _def_num_un_op(_class, _op_fn, _op, value) #define def_math_fn(_fn) \ Value* \ _fn##_cf(Value** arg_list, int count) \ { \ check_arg_count(_fn, 1, count); \ return Float::intern((float)_fn(arg_list[0]->to_float())); \ } #define def_angle_trig_fn(_fn) \ Value* \ _fn##_cf(Value** arg_list, int count) \ { \ check_arg_count(_fn, 1, count); \ return Float::intern(RadToDeg((float)_fn(arg_list[0]->to_float()))); \ } #define def_float_trig_fn(_fn) \ Value* \ _fn##_cf(Value** arg_list, int count) \ { \ check_arg_count(_fn, 1, count); \ return Float::intern((float)_fn(DegToRad(arg_list[0]->to_float()))); \ } #define def_math_bin_fn(_fn) \ Value* \ _fn##_cf(Value** arg_list, int count) \ { \ check_arg_count(_fn, 2, count); \ return Float::intern((float)_fn(arg_list[0]->to_float(), \ arg_list[1]->to_float())); \ } #define def_angle_trig_bin_fn(_fn) \ Value* \ _fn##_cf(Value** arg_list, int count) \ { \ check_arg_count(_fn, 2, count); \ return Float::intern(RadToDeg((float)_fn(arg_list[0]->to_float(), \ arg_list[1]->to_float()))); \ } #define def_num_prop_accessors(_class, _prop, _member, _type, _conv ) \ Value* \ _class::get_##_prop(Value** arg_list, int count) \ { \ return _type::intern(_member); \ } \ Value* \ _class::set_##_prop(Value** arg_list, int count) \ { \ Value* val = arg_list[0]; \ _member = val->_conv(); \ return val; \ } #define def_prop_accessors(_class, _prop, _member, _type, _conv ) \ Value* \ _class::get_##_prop(Value** arg_list, int count) \ { \ return new _type (_member); \ } \ Value* \ _class::set_##_prop(Value** arg_list, int count) \ { \ Value* val = arg_list[0]; \ _member = val->_conv(); \ return val; \ } #define def_fn_prop_accessors(_class, _prop, _getter, _setter) \ Value* \ _class::get_##_prop(Value** arg_list, int count) \ { \ return _getter; \ } \ Value* \ _class::set_##_prop(Value** arg_list, int count) \ { \ Value* val = arg_list[0]; \ _setter; \ return val; \ } #define def_fn_prop_getter(_class, _prop, _getter) \ Value* \ _class::get_##_prop(Value** arg_list, int count) \ { \ return _getter; \ } #define def_fn_prop_setter(_class, _prop, _setter) \ Value* \ _class::set_##_prop(Value** arg_list, int count) \ { \ Value* val = arg_list[0]; \ _setter; \ return val; \ } #define def_float_prop_accessors(_class, _prop, _member) \ def_num_prop_accessors(_class, _prop, _member, Float, to_float) #define def_int_prop_accessors(_class, _prop, _member) \ def_num_prop_accessors(_class, _prop, _member, Integer, to_int) #define def_point3_prop_accessors(_class, _prop, _member) \ def_fn_prop_accessors(_class, _prop, new Point3Value (_member), _member = val->to_point3()) #define def_angle_prop_accessors(_class, _prop, _member) \ def_fn_prop_accessors(_class, _prop, Float::intern(RadToDeg(_member)), _member = DegToRad(val->to_float())) #define def_time_bin_op(_op_fn, _op) \ _def_bin_op(MSTime, to_timevalue, _op_fn, _op, time) #define def_time_rel_op(_op_fn, _rel_op) \ _def_rel_op(MSTime, to_timevalue, _op_fn, _rel_op, time) #define def_time_un_op(_op_fn, _op) \ _def_un_op(MSTime, _op_fn, _op, time) #define def_quat_bin_op(_class, _conv, _op_fn, _op) \ _def_bin_op(_class, _conv, _op_fn, _op, q) #define def_quat_rel_op(_class, _conv, _op_fn, _rel_op) \ _def_rel_op(_class, _conv, _op_fn, _rel_op, q) #define def_quat_un_op(_class, _op_fn, _op) \ _def_un_op(_class, _op_fn, _op, q) #define def_new_quat_fn(_fn, _arg_count, _call) \ Value* \ QuatValue::_fn##_vf(Value** arg_list, int count) \ { \ check_arg_count(_fn, _arg_count, count + 1); \ return new QuatValue (_call); \ } #define def_mut_quat_fn(_fn, _arg_count, _call) \ Value* \ QuatValue::_fn##_vf(Value** arg_list, int count) \ { \ check_arg_count(_fn, _arg_count, count + 1); \ _call; \ return this; \ } #define def_new_mat_fn(_fn, _arg_count, _call) \ Value* \ Matrix3Value::_fn##_vf(Value** arg_list, int count) \ { \ check_arg_count(_fn, _arg_count, count + 1); \ return new Matrix3Value (_call); \ } #define def_mut_mat_fn(_fn, _arg_count, _call) \ Value* \ Matrix3Value::_fn##_vf(Value** arg_list, int count) \ { \ check_arg_count(_fn, _arg_count, count + 1); \ _call; \ return this; \ } #define def_mat_primitive(_fn, _arg_count, _call) \ Value* \ _fn##_cf(Value** arg_list, int count) \ { \ check_arg_count(_fn, _arg_count, count); \ return new Matrix3Value (_call); \ } #define def_mat_bin_op(_class, _conv, _op_fn, _op) \ _def_bin_op(_class, _conv, _op_fn, _op, m) #define def_mat_rel_op(_class, _conv, _op_fn, _rel_op) \ _def_rel_op(_class, _conv, _op_fn, _rel_op, m) #define def_mat_un_op(_class, _op_fn, _op) \ _def_un_op(_class, _op_fn, _op, m) // LAM: 2/27/01 - modified following to invalidate foreground/background rectangle instead of just // foreground #define def_bool_node_fns(name, getter, setter) \ Value* node_get_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Interval& valid) \ { \ return ((INode*)obj)->getter() ? &true_value : &false_value; \ } \ void node_set_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Value* val) \ { \ ((INode*)obj)->setter(val->to_bool()); \ InvalidateNodeRect((INode*)obj,t); \ } #define def_bool_node_getter(name, getter) \ Value* node_get_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Interval& valid) \ { \ return ((INode*)obj)->getter() ? &true_value : &false_value; \ } \ void node_set_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Value* val) \ { \ throw RuntimeError (_T("Property not settable: "), #name); \ } #define def_ulong_node_fns(name, getter, setter) \ Value* node_get_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Interval& valid) \ { \ return Integer::intern((int)((INode*)obj)->getter()); \ } \ void node_set_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Value* val) \ { \ ((INode*)obj)->setter((ULONG)val->to_int()); \ InvalidateNodeRect((INode*)obj,t); \ } #define def_color_node_fns(name, getter, setter) \ Value* node_get_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Interval& valid) \ { \ DWORD rgb = ((INode*)obj)->getter(); \ return ColorValue::intern(GetRValue(rgb) / 255.0f, GetGValue(rgb) / 255.0f, GetBValue(rgb) / 255.0f); \ } \ void node_set_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Value* val) \ { \ AColor c; \ c = val->to_acolor(); \ ((INode*)obj)->setter(RGB((BYTE)(c.r * 255), (BYTE)(c.g * 255), (BYTE)(c.b * 255))); \ InvalidateNodeRect((INode*)obj,t); \ } // LAM: 2/27/01 - use following for node properties that don't require a redraw // The following defines has been added // in 3ds max 4.2. If your plugin utilizes this new // mechanism, be sure that your clients are aware that they // must run your plugin with 3ds max version 4.2 or higher. #define def_bool_node_noredraw_fns(name, getter, setter) \ Value* node_get_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Interval& valid) \ { \ return ((INode*)obj)->getter() ? &true_value : &false_value; \ } \ void node_set_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Value* val) \ { \ ((INode*)obj)->setter(val->to_bool()); \ } #define def_ulong_node_noredraw_fns(name, getter, setter) \ Value* node_get_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Interval& valid) \ { \ return Integer::intern((int)((INode*)obj)->getter()); \ } \ void node_set_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Value* val) \ { \ ((INode*)obj)->setter((ULONG)val->to_int()); \ } #define def_color_node_noredraw_fns(name, getter, setter) \ Value* node_get_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Interval& valid) \ { \ DWORD rgb = ((INode*)obj)->getter(); \ return ColorValue::intern(GetRValue(rgb) / 255.0f, GetGValue(rgb) / 255.0f, GetBValue(rgb) / 255.0f); \ } \ void node_set_##name(ReferenceTarget* obj, Value* prop, TimeValue t, Value* val) \ { \ AColor c; \ c = val->to_acolor(); \ ((INode*)obj)->setter(RGB((BYTE)(c.r * 255), (BYTE)(c.g * 255), (BYTE)(c.b * 255))); \ } // End of 3ds max 4.2 Extension