functions.h

Go to the documentation of this file.
00001 /*      Functions.h - the Function family class - primitives, generics
00002  *
00003  *      Copyright (c) John Wainwright, 1996
00004  *      
00005  */
00006 
00007 #pragma once
00008 
00009 #include "arrays.h"
00010 // forward declarations
00011 class HashTable;
00012 class FPInterfaceProxy;
00013 
00014 #undef def_generic
00015 #define def_generic(fn, name)   \
00016             ScripterExport Value* fn##_vf(Value** arglist, int arg_count)
00017 
00018 #define FPS_CACHE_SIZE 512
00019 
00020 // internally used structure
00021 struct DumpValueData
00022 {
00023     Value**     locals;
00024     int         indentLevel;
00025     Value*      owner;
00026 };
00027 
00028 
00029 /* --- function base class -- */
00030 
00031 visible_class (Function)
00032 
00033 class Function : public Value
00034 {
00035 // Whether the function can be called from debugger thread stored in Collectable::flags3 - bit 0. Default is false.
00036 public:
00037     MCHAR*      name;
00038     MCHAR*      struct_name;    // packaged in a struct if non-null
00039 
00040                    Function() { name = NULL; struct_name = NULL; }
00041     ScripterExport Function(MCHAR* name, MCHAR* struct_name=NULL);
00042     ScripterExport Function(MCHAR* name, MCHAR* struct_name, bool debuggerSafe);
00043     ScripterExport ~Function();
00044 
00045                 classof_methods (Function, Value);
00046 #   define      is_function(v) ((v)->_is_function())
00047     BOOL        _is_function() { DbgAssert(!is_sourcepositionwrapper(this)); return 1; }
00048 
00049     ScripterExport void sprin1(CharStream* s);
00050     ScripterExport void export_to_scripter();
00051 };
00052 
00053 /* ----------------  call context base class ----------------- */
00054 
00055 class CallContext 
00056 {
00057     CallContext* previous;
00058 public:
00059     CallContext() : previous(NULL) { }
00060     CallContext(CallContext* previous) : previous(previous) { }
00061 
00062     // called by fn applier to establish context AFTER arguments eval'd 
00063     virtual void push_context() { if (previous) previous->push_context(); }
00064     virtual void pop_context() { if (previous) previous->pop_context(); }
00065 };
00066 
00067 /* ----------------------- Generics ------------------------- */
00068 
00069 visible_class (Generic)
00070 
00071 class Generic : public Function
00072 {
00073 public:
00074     value_vf    fn_ptr;
00075 
00076                 Generic() { }
00077  ScripterExport Generic(MCHAR* name, value_vf fn, MCHAR* struct_name = NULL);
00078  ScripterExport Generic(MCHAR* name, value_vf fn, MCHAR* struct_name, short init_flags=0);
00079                 Generic(MCHAR* name) : Function(name) { }
00080 
00081                 classof_methods (Generic, Function);
00082     BOOL        _is_function() { DbgAssert(!is_sourcepositionwrapper(this)); return 1; }
00083     ScripterExport void init(MCHAR* name, value_vf fn);
00084     void        collect() { delete this; }
00085 
00086     ScripterExport Value* apply(Value** arglist, int count, CallContext* cc=NULL);
00087 };
00088 
00089 visible_class (MappedGeneric)
00090 
00091 class MappedGeneric : public Generic
00092 {
00093 public:
00094                 MappedGeneric() { }
00095  ScripterExport MappedGeneric(MCHAR* name, value_vf fn);
00096  ScripterExport MappedGeneric(MCHAR* name, value_vf fn, short init_flags);
00097                 MappedGeneric(MCHAR* name) : Generic(name) { }
00098 
00099                 classof_methods (MappedGeneric, Generic);
00100     BOOL        _is_function() { DbgAssert(!is_sourcepositionwrapper(this)); return 1; }
00101     void        collect() { delete this; }
00102 
00103     ScripterExport Value* apply(Value** arglist, int count, CallContext* cc=NULL);
00104 };
00105 
00106 visible_class (NodeGeneric)
00107 
00108 class NodeGeneric : public MappedGeneric
00109 {
00110 public:
00111  ScripterExport NodeGeneric(MCHAR* name, value_vf fn);
00112  ScripterExport NodeGeneric(MCHAR* name, value_vf fn, short init_flags);
00113                 NodeGeneric(MCHAR* name) : MappedGeneric(name) { }
00114 
00115                 classof_methods (NodeGeneric, MappedGeneric);
00116     BOOL        _is_function() { DbgAssert(!is_sourcepositionwrapper(this)); return 1; }
00117     void        collect() { delete this; }
00118 
00119     ScripterExport Value* apply(Value** arglist, int count, CallContext* cc=NULL);
00120 };
00121 
00122 /* -------------------------- Primitives ------------------------------ */
00123 
00124 enum primitive_flag
00125 {
00126     LAZY_PRIMITIVE  =   0x0001, // don't pre-evaluate args for lazy primitives
00127     DEBUGGER_SAFE   =   0x0002, // safe to call from debugger
00128 };
00129 
00130 visible_class (Primitive)
00131 
00132 class Primitive : public Function
00133 { 
00134 public:
00135     short       flags;
00136     value_cf    fn_ptr;
00137 
00138                 Primitive() { flags=0; }
00139  ScripterExport Primitive(MCHAR* name, value_cf fn, short init_flags=0);
00140  ScripterExport Primitive(MCHAR* name, MCHAR* structure, value_cf fn, short init_flags=0);
00141                 Primitive(MCHAR* name) : Function(name) { flags=0; }
00142 
00143                 classof_methods (Primitive, Function);
00144     BOOL        _is_function() { DbgAssert(!is_sourcepositionwrapper(this)); return 1; }
00145     void        collect() { delete this; }
00146 
00147     ScripterExport Value* apply(Value** arglist, int count, CallContext* cc=NULL);
00148 };
00149 
00150 visible_class (MappedPrimitive)
00151 
00152 class MappedPrimitive : public Primitive
00153 { 
00154 public:
00155  ScripterExport MappedPrimitive(MCHAR* name, value_cf fn);
00156  ScripterExport MappedPrimitive(MCHAR* name, value_cf fn, short init_flags);
00157 
00158                 classof_methods (MappedPrimitive, Primitive);
00159     BOOL        _is_function() { DbgAssert(!is_sourcepositionwrapper(this)); return 1; }
00160     void        collect() { delete this; }
00161 
00162     ScripterExport Value* apply(Value** arglist, int count, CallContext* cc=NULL);
00163 };
00164 
00165 /* ----- */
00166 
00167 visible_class (MAXScriptFunction)
00168 
00169 class MAXScriptFunction : public Function
00170 {
00171 public:
00172     short       parameter_count;
00173     short       local_count;
00174     short       keyparm_count;
00175     short       flags;
00176     Value**     keyparms;
00177     Value*      body;
00178     HashTable*  local_scope;
00179     value_cf    c_callable_fn;
00180     Array*      paramNames;
00181     Value*      owner;
00182 
00183  ScripterExport MAXScriptFunction(MCHAR* name, int parm_count, int keyparm_count, Value** keyparms,
00184                                   int local_count, Value* body, HashTable* local_scope, short flags = 0);
00185  ScripterExport MAXScriptFunction(MCHAR* name, int parm_count, int keyparm_count, Value** keyparms,
00186                                   int local_count, Value* body, HashTable* local_scope, Array* param_names, 
00187                                   Value* owner, short flags = 0);
00188                 ~MAXScriptFunction();
00189 #   define      is_maxscriptfunction(v) ((DbgVerify(!is_sourcepositionwrapper(v)), (v))->tag == class_tag(MAXScriptFunction))
00190 
00191                 classof_methods (MAXScriptFunction, Function);
00192     BOOL        _is_function() { DbgAssert(!is_sourcepositionwrapper(this)); return TRUE; }
00193     void        collect() { delete this; }
00194     void        gc_trace();
00195     void        sprin1(CharStream* s);
00196 
00197     Value*      apply(Value** arglist, int count, CallContext* cc=NULL);
00198     Value*      apply_no_alloc_frame(Value** arglist, int count, CallContext* cc=NULL);
00199 
00200     value_cf    get_c_callable_fn();
00201 
00202     Value*      operator()(Value** arg_list, int count);
00203 
00204     // added 3/21/05. Used by debugger to dump locals, parms, and externals to standard out
00205     void        dump_local_vars_params_and_externals(Value** paramsFrame, Value** localsFrame, int indentLevel);
00206 
00207 protected:
00208     Value*      wrap_arg(Value* arg);
00209 };
00210 
00211 #define FN_MAPPED_FN    0x0001      // declared a collection-mapped function
00212 #define FN_BODY_FN      0x0002      // a loop or other body function, don't trap exits here
00213 #define FN_HAS_REFARGS  0x0004      // function has reference arguments
00214 #define FN_MAPPED_EVAL  0x0008      // set while evaluating a mapped function on each item
00215 
00216 
00217 // StructMethods wrap member functions accessed on a struct instance
00218 // their apply() sets up the appropriate struct instance thread-local
00219 // for member data access thunks
00220 class Struct;
00221 class StructMethod : public Value
00222 {
00223 public:
00224     Struct* this_struct;
00225     Value*  fn;
00226 
00227     ScripterExport StructMethod(Struct* t, Value* f);
00228 
00229     void    gc_trace();
00230     void    collect() { delete this; }
00231     void    sprin1(CharStream* s) { fn->sprin1(s); }
00232     BOOL    _is_function() { return fn->_is_function(); }
00233 
00234 #   define is_structMethod(v) ((DbgVerify(!is_sourcepositionwrapper(v)), (v))->tag == INTERNAL_STRUCT_METHOD_TAG)  // LAM - defect 307069
00235     Value* classOf_vf(Value** arg_list, int count) { return fn->classOf_vf(arg_list, count); }
00236     Value* superClassOf_vf(Value** arg_list, int count) { return fn->superClassOf_vf(arg_list, count); }
00237     Value* isKindOf_vf(Value** arg_list, int count) { return fn->isKindOf_vf(arg_list, count); }
00238     BOOL   is_kind_of(ValueMetaClass* c) { return fn->is_kind_of(c); }
00239     Value* get_property(Value** arg_list, int count) { return fn->get_property(arg_list, count); }
00240     Value* eval() { return fn->eval(); }
00241     Value* apply(Value** arglist, int count, CallContext* cc=NULL);
00242     Value* apply_no_alloc_frame(Value** arglist, int count, CallContext* cc=NULL); // LAM - 11/16/02
00243 };
00244 
00245 // call context for StructMethod
00246 // used internally when calling a structure method to save current active structure, set the specified structure
00247 // as the current structure, and afer the call to restore the original current structure
00248 class SMCallContext : public CallContext
00249 {
00250     Struct* save_struct;
00251     Struct* this_struct;
00252 public:
00253     SMCallContext(Struct* strct, CallContext* previous=NULL);
00254     void push_context(); 
00255     void pop_context();
00256 };
00257 
00258 // LAM - 9/6/02 - defect 291499
00259 // PluginMethods wrap member functions accessed on a plugin instance
00260 // their apply() sets up the appropriate plugin instance thread-local
00261 // for member data access thunks
00262 class MSPlugin;
00263 class PluginMethod : public Value
00264 {
00265 public:
00266     MSPlugin* this_plugin;
00267     Value*  fn;
00268 
00269     ScripterExport PluginMethod(MSPlugin* t, Value* f);
00270 
00271     void    gc_trace();
00272     void    collect() { delete this; }
00273     void    sprin1(CharStream* s) { fn->sprin1(s); }
00274     BOOL    _is_function() { return fn->_is_function(); }
00275 
00276 #   define is_pluginMethod(v) ((DbgVerify(!is_sourcepositionwrapper(v)), (v))->tag == INTERNAL_MSPLUGIN_METHOD_TAG)
00277     Value* classOf_vf(Value** arg_list, int count) { return fn->classOf_vf(arg_list, count); }
00278     Value* superClassOf_vf(Value** arg_list, int count) { return fn->superClassOf_vf(arg_list, count); }
00279     Value* isKindOf_vf(Value** arg_list, int count) { return fn->isKindOf_vf(arg_list, count); }
00280     BOOL   is_kind_of(ValueMetaClass* c) { return (is_pluginMethod(c)) ? 1 : Value::is_kind_of(c); }
00281     Value* get_property(Value** arg_list, int count) { return fn->get_property(arg_list, count); }
00282     Value* eval() { return fn->eval(); }
00283     Value* apply(Value** arg_list, int count, CallContext* cc=NULL);
00284     Value* apply_no_alloc_frame(Value** arg_list, int count, CallContext* cc=NULL);
00285 
00286 };
00287 
00288 // UserProp & UserGeneric instances represent dynamically-added, user-defined generics
00289 //  on built-in classes.  They are kept in sorted tables in ValueMetaClass instances,
00290 // suitable for bsearching.
00291 class UserProp
00292 {
00293 public:
00294     Value*      prop;
00295     value_cf    getter;
00296     value_cf    setter;
00297                 UserProp (Value* p, value_cf g, value_cf s) { prop = p; getter = g; setter = s; }
00298 };
00299 
00300 class UserGeneric
00301 {
00302 public:
00303     Value*      name;
00304     value_cf    fn;
00305                 
00306                 UserGeneric(Value* n, value_cf f) { name = n; fn = f; }
00307 };
00308 
00309 // UserGenericValue is the scripter-visible generic fn value that dispatches the
00310 // UserGeneric 'methods' in a target object's class
00311 
00312 visible_class (UserGenericValue)
00313 
00314 class UserGenericValue : public Function
00315 {
00316 public:
00317     Value*      fn_name;
00318     Value*      old_fn;   // if non-NULL, the original global fn that this usergeneric replaced
00319                 
00320  ScripterExport UserGenericValue(Value* name, Value* old_fn);
00321 
00322                 classof_methods (UserGenericValue, Function);
00323     BOOL        _is_function() { DbgAssert(!is_sourcepositionwrapper(this)); return TRUE; }
00324     void        collect() { delete this; }
00325     void        gc_trace();
00326 
00327     Value*      apply(Value** arglist, int count, CallContext* cc=NULL);
00328 };
00329 
00330 #define def_user_prop(_prop, _cls, _getter, _setter)        \
00331     _cls##_class.add_user_prop(#_prop, _getter, _setter)
00332 
00333 #define def_user_generic(_fn, _cls, _name)                  \
00334     _cls##_class.add_user_generic(#_name, _fn)
00335 
00336 
00337 // ------- MAXScript Function Publishing interface ----------------------
00338 
00339 #include "..\..\ifnpub.h"
00340 #include "..\..\GetCOREInterface.h"
00341 
00342 class InterfaceMethod;
00343 class FPMixinInterfaceValue;
00344 class FPEnum;
00345 
00346 // FnPub function, a function published by a plugin using theFnPub system
00347 //     automatically exposed by MAXScript boot code during intial plugin scan
00348 
00349 visible_class (InterfaceFunction)
00350 
00351 class InterfaceFunction : public Function
00352 {
00353 public:
00354     FPInterfaceDesc* fpid;
00355     FPFunctionDef*   fd;
00356 
00357                 InterfaceFunction(FPInterface* fpi, FPFunctionDef* fd);
00358                 ~InterfaceFunction();
00359 
00360                 classof_methods (InterfaceFunction, Function);
00361     BOOL        _is_function() { DbgAssert(!is_sourcepositionwrapper(this)); return TRUE; }
00362     void        collect() { delete this; }
00363     void        gc_trace();
00364     void        sprin1(CharStream* s);
00365 
00366     Value*      apply(Value** arglist, int count, CallContext* cc=NULL);
00367     Value*      get_property(Value** arg_list, int count);
00368 
00369     // parameter conversion utilities
00370     ScripterExport static void    val_to_FPValue(Value* v, ParamType2 type, FPValue& fpv, FPEnum* e, Tab<void*> *stringStorage, Array* valueStore);
00371     ScripterExport static void    val_to_FPValue(Value* v, ParamType2 type, FPValue& fpv, FPEnum* e, Tab<void*> *stringStorage);
00372     ScripterExport static void    val_to_FPValue(Value* v, ParamType2 type, FPValue& fpv, FPEnum* e=NULL);
00373     ScripterExport static Value*  FPValue_to_val(FPValue& fpv, FPEnum* e=NULL);
00374     ScripterExport static void    release_param(FPValue& fpv, ParamType2 type, Value* v, FPEnum* e=NULL);
00375     ScripterExport static void    init_param(FPValue& fpv, ParamType2 type);
00376     ScripterExport static void    validate_params(FPInterface* fpi, FunctionID fid, FPParamDef* pd, ParamType2 type, int paramNum, FPValue& val, Value* v);
00377     ScripterExport static FPEnum* FindEnum(short id, FPInterfaceDesc* fpid);
00378 };
00379 
00380 // ValueConverter - Routines to convert between FPValue and Value
00381 #define VALUECONVERTER_INTERFACE_ID Interface_ID(0x19f37b9f, 0x39ed5680)
00382 class ValueConverter : public FPStaticInterface
00383 {
00384 public:
00385     enum FPValueSubtype
00386     {
00387         SUBTYPE_NONE=0,
00388         SUBTYPE_IROLLUPWINDOW,
00389     };
00390 
00391     virtual void    val_to_FPValue(Value* v, ParamType2 type, FPValue& fpv, FPEnum* e, Tab<void*> *stringStorage, Array* valueStore) = 0;
00392     virtual void    val_to_FPValue(Value* v, ParamType2 type, FPValue& fpv, FPEnum* e, Tab<void*> *stringStorage) = 0;
00393     virtual void    val_to_FPValue(Value* v, ParamType2 type, FPValue& fpv, FPEnum* e=NULL) = 0;
00394     virtual Value*  FPValue_to_val(FPValue& fpv, FPEnum* e=NULL, FPValueSubtype subtype=SUBTYPE_NONE) = 0;
00395     virtual void    release_param(FPValue& fpv, ParamType2 type, Value* v, FPEnum* e=NULL) = 0;
00396     virtual void    init_param(FPValue& fpv, ParamType2 type) = 0;
00397     virtual void    validate_params(FPInterface* fpi, FunctionID fid, FPParamDef* pd, ParamType2 type, int paramNum, FPValue& val, Value* v) = 0;
00398     virtual FPEnum* FindEnum(short id, FPInterfaceDesc* fpid) = 0;
00399 
00400     // This is how client code can get to the ValueConverter instance
00401     static ValueConverter* GetValueConverter()
00402     {
00403         return static_cast<ValueConverter*>(GetCOREInterface(VALUECONVERTER_INTERFACE_ID));
00404     }
00405 };
00406 
00407 // InterfaceMethod - wraps an InterfaceFunction and its target object for shorthand mixin calls
00408 class InterfaceMethod : public InterfaceFunction
00409 {
00410 private:
00411                 InterfaceMethod(FPMixinInterfaceValue* fpiv, FPFunctionDef* fd);
00412     static      InterfaceMethod* interface_method_cache[FPS_CACHE_SIZE];
00413     friend void Collectable::gc();
00414     friend void Collectable::mark();
00415 public:
00416     FPMixinInterfaceValue* fpiv;
00417 
00418     static ScripterExport InterfaceMethod* intern(FPMixinInterfaceValue* fpiv, FPFunctionDef* fd);
00419                 ~InterfaceMethod();
00420 
00421                 def_generic ( isDeleted,            "isDeleted");   // LAM: 11/23/01 - added - doesn't break SDK
00422                 use_generic( eq,                    "=" );          // LAM: 11/23/01 - added - doesn't break SDK
00423                 use_generic( ne,                    "!=" );         // LAM: 11/23/01 - added - doesn't break SDK
00424     void        collect() { delete this; }
00425     void        gc_trace();
00426 
00427     Value*      apply(Value** arglist, int count, CallContext* cc=NULL);
00428 };
00429 
00430 // Action predicate function wrappers...
00431 visible_class (ActionPredicate)
00432 
00433 class ActionPredicate : public InterfaceFunction
00434 {
00435 public:
00436     short       pred;
00437 
00438     ActionPredicate(FPInterface* fpi, FPFunctionDef* fd, short pred);
00439 
00440                 classof_methods (ActionPredicate, Function);
00441     BOOL        _is_function() { DbgAssert(!is_sourcepositionwrapper(this)); return TRUE; }
00442     void        collect() { delete this; }
00443 
00444     Value*      apply(Value** arglist, int count, CallContext* cc=NULL);
00445 };
00446 
00447 // IObject, generic wrapper for objects that inherit from IObject
00448 //    this is a way to give simple interface-based wrappers to 
00449 //    classes in MAX or 3rd-party plugins that MAXScript knows
00450 //    nothing about.  The IObject instance must implement GetInterface()
00451 
00452 visible_class (IObjectValue)
00453 
00454 class IObjectValue : public Value
00455 {
00456 public:
00457     IObject* iobj;                  // the IObject pointer
00458 
00459             IObjectValue(IObject* io);
00460            ~IObjectValue();
00461 #   define  is_iobject(v) ((DbgVerify(!is_sourcepositionwrapper(v)), (v))->tag == class_tag(IObjectValue))
00462 
00463             classof_methods (IObjectValue, Value);
00464     void    collect() { delete this; }
00465     void    sprin1(CharStream* s);
00466 
00467     MSTR    to_filename(); // returns guidstring if wraps AssetUser
00468     void    to_fpvalue(FPValue& v) { v.iobj = iobj; v.type = TYPE_IOBJECT; }
00469 
00470     def_generic (show_interfaces,  "showInterfaces"); 
00471     def_generic (get_interfaces, "getInterfaces");
00472     def_generic (get_interface, "getInterface");
00473 
00474 // End of 3ds max 4.2 Extension
00475 
00476     BaseInterface* GetInterface(Interface_ID id) { return iobj->GetInterface(id); }
00477 
00478     //accesses interfaces on the IObject
00479     Value*  get_property(Value** arg_list, int count);
00480     Value*  set_property(Value** arg_list, int count);
00481 };
00482 
00483 // FPInterfaceValue, represents  FPInterfaces in MAXScript
00484 
00485 visible_class (FPInterfaceValue)
00486 
00487 class FPInterfaceValue : public Value, public InterfaceNotifyCallback
00488 {
00489 public:
00490     FPInterface* fpi;           // interface
00491     HashTable*   fns;           // interface fn lookup
00492     HashTable*   props;         // interface prop lookup
00493     FPInterface::LifetimeType lifetime; // interface lifetime control type
00494     static bool  enable_test_interfaces;  // test interface enable flag
00495     // Whether to call fpi->ReleaseInterface stored in Collectable::flags3 - bit 0
00496 
00497     ScripterExport FPInterfaceValue(FPInterface* fpi);   
00498     FPInterfaceValue(FPInterfaceProxy* proxy);
00499     ~FPInterfaceValue();
00500 
00501     // Needed to solve ambiguity between Collectable's operators and MaxHeapOperators
00502     using Collectable::operator new;
00503     using Collectable::operator delete;
00504 
00505 #   define  is_fpstaticinterface(v) ((DbgVerify(!is_sourcepositionwrapper(v)), (v))->tag == class_tag(FPInterfaceValue))
00506 
00507             classof_methods (FPInterfaceValue, Value);
00508             def_generic ( show_interface,       "showInterface"); // LAM: 08/29/00
00509             def_generic ( get_props,            "getPropNames"); // LAM: added 2/1/02
00510             def_generic ( isDeleted,            "isDeleted");   // LAM: 11/23/01 - added - doesn't break SDK
00511             use_generic( eq,                    "=" );          // LAM: 11/23/01 - added - doesn't break SDK
00512             use_generic( ne,                    "!=" );         // LAM: 11/23/01 - added - doesn't break SDK
00513     void    collect() { delete this; }
00514     void    gc_trace();
00515     void    sprin1(CharStream* s);
00516 
00517 // The following method has been added
00518 // in 3ds max 4.2.  If your plugin utilizes this new
00519 // mechanism, be sure that your clients are aware that they
00520 // must run your plugin with 3ds max version 4.2 or higher.
00521 
00522     void    to_fpvalue(FPValue& v) { 
00523         resolve_proxy();
00524         v.fpi = fpi; 
00525         v.type = TYPE_INTERFACE; 
00526     }
00527 
00528 // End of 3ds max 4.2 Extension
00529 
00530     // from InterfaceNotifyCallback
00531     void    InterfaceDeleted(BaseInterface* bi) { UNUSED_PARAM(bi); fpi = NULL; }  
00532 
00533     // accesses methods & props in the interface
00534     Value*  _get_property(Value* prop);
00535     Value*  _set_property(Value* prop, Value* val);
00536 
00537     Value*  get_property(Value** arg_list, int count);
00538     Value*  set_property(Value** arg_list, int count);
00539 
00540     static void UpdateEditorOnResolve(bool update = true);
00541 
00542 private:
00543     void    resolve_proxy();
00544     void    set_interface(FPInterface* fpi);
00545 
00546     FPInterfaceProxy*   m_fpip;
00547     static bool         s_updateEditorOnResolve;
00548 };
00549 
00550 extern ScripterExport void print_FP_interface(CharStream* out, FPInterface* fpi, bool getPropNames = true, 
00551                bool getMethodNames = true, bool getInterfaceNames = true, bool getActionTables = true);
00552 
00553 // FPMixinInterfaceValue provides wrappers for mixin interfaces on individual target objects
00554 //  stored in a cache for fast retrieval and to minimize over-consing
00555 // Warning: FPMixinInterfaceValue can wrap a FPStaticInterface. If accessing FPMixinInterface
00556 // specific items, test 'fpi->GetDesc()->flags & FP_MIXIN' first.
00557 
00558 visible_class (FPMixinInterfaceValue)
00559 
00560 class FPMixinInterfaceValue : public Value, public InterfaceNotifyCallback
00561 {
00562 private:
00563             FPMixinInterfaceValue(FPInterface* fpi);
00564            ~FPMixinInterfaceValue();
00565     static  FPMixinInterfaceValue* FPMixinInterfaceValue::interface_cache[128];
00566     friend void Collectable::gc();
00567     friend void Collectable::mark();
00568 public:
00569     FPInterface* fpi;                       // interface
00570     FPInterface::LifetimeType lifetime;     // interface lifetime control type
00571     // Whether to call fpi->ReleaseInterface stored in Collectable::flags3 - bit 0
00572 
00573     // Needed to solve ambiguity between Collectable's operators and MaxHeapOperators
00574     using Collectable::operator new;
00575     using Collectable::operator delete;
00576 
00577     static  ScripterExport FPMixinInterfaceValue* intern(Value* prop_name, Value* target);
00578     static  ScripterExport FPMixinInterfaceValue* intern(FPInterface* fpi);
00579 #   define  is_fpmixininterface(v) ((DbgVerify(!is_sourcepositionwrapper(v)), (v))->tag == class_tag(FPMixinInterfaceValue))
00580 
00581             classof_methods (FPMixinInterfaceValue, Value);
00582             def_generic ( show_interface,       "showInterface"); // LAM: 08/29/00
00583             def_generic ( isDeleted,            "isDeleted");   // LAM: 11/23/01 - added - doesn't break SDK
00584             use_generic( eq,                    "=" );          // LAM: 11/23/01 - added - doesn't break SDK
00585             use_generic( ne,                    "!=" );         // LAM: 11/23/01 - added - doesn't break SDK
00586             def_generic ( get_props,            "getPropNames"); // LAM: added 2/1/02
00587     void    collect() { delete this; }
00588     void    sprin1(CharStream* s);
00589 
00590 // The following method has been added
00591 // in 3ds max 4.2.  If your plugin utilizes this new
00592 // mechanism, be sure that your clients are aware that they
00593 // must run your plugin with 3ds max version 4.2 or higher.
00594 
00595     void    to_fpvalue(FPValue& v) { v.fpi = fpi; v.type = TYPE_INTERFACE; }
00596 
00597 // End of 3ds max 4.2 Extension
00598 
00599     // from InterfaceNotifyCallback
00600     void    InterfaceDeleted(BaseInterface* bi); 
00601 
00602     // accesses methods & props in the interface
00603     Value*  _get_property(Value* prop);
00604     Value*  _set_property(Value* prop, Value* val);
00605 
00606     Value*  get_property(Value** arg_list, int count);
00607     Value*  set_property(Value** arg_list, int count);
00608 };
00609 
00610 // FPStaticMethodInterfaceValue provides wrappers for static interfaces that
00611 // have been registered with individual Value metaclasses as property
00612 // interfaces on instances of the metaclasses' class, such that calls
00613 // on methods in these interfaces pass the intance along as the first
00614 // argument wrapped in an FPValue.
00615 
00616 // these are used to allow factored static interfaces (such as meshOps)
00617 // to appear as though they are mixin interfaces on several MAXScript value
00618 // classes (such as node, baseobject, meshvalue), in which the target object
00619 // is sent as a polymorphic first argument (via FPValue) to static interface
00620 // method call, rather than as a 'this' pointer to a virtual mixin interface method
00621 
00622 visible_class (FPStaticMethodInterfaceValue)
00623 
00624 class FPStaticMethodInterfaceValue : public Value, public InterfaceNotifyCallback
00625 {
00626 private:
00627             FPStaticMethodInterfaceValue(FPInterface* fpi, ParamType2 type, void* object);
00628            ~FPStaticMethodInterfaceValue();
00629     static  FPStaticMethodInterfaceValue* interface_cache[FPS_CACHE_SIZE];
00630     friend void Collectable::gc();
00631     friend void Collectable::mark();
00632 public:
00633     FPInterface* fpi;           // interface
00634     FPValue      value;         // the target object as FPValue first argument
00635     FPInterface::LifetimeType lifetime; // interface lifetime control type
00636     // Whether to call fpi->ReleaseInterface stored in Collectable::flags3 - bit 0
00637 
00638     // Needed to solve ambiguity between Collectable's operators and MaxHeapOperators
00639     using Collectable::operator new;
00640     using Collectable::operator delete;
00641 
00642     static  ScripterExport FPStaticMethodInterfaceValue* intern(FPInterface* fpi, ParamType2 type, void* object);
00643 #   define  is_fpstaticmethodinterface(v) ((DbgVerify(!is_sourcepositionwrapper(v)), (v))->tag == class_tag(FPStaticMethodInterfaceValue))
00644 
00645             classof_methods (FPStaticMethodInterfaceValue, Value);
00646             def_generic ( show_interface,       "showInterface"); // LAM: 08/29/00
00647             def_generic ( isDeleted,            "isDeleted");   // LAM: 11/23/01 - added - doesn't break SDK
00648             use_generic( eq,                    "=" );          // LAM: 11/23/01 - added - doesn't break SDK
00649             use_generic( ne,                    "!=" );         // LAM: 11/23/01 - added - doesn't break SDK
00650             def_generic ( get_props,            "getPropNames"); // LAM: added 2/1/02
00651     void    collect() { delete this; }
00652     void    sprin1(CharStream* s);
00653 
00654     // from InterfaceNotifyCallback
00655     void    InterfaceDeleted(BaseInterface* bi) { UNUSED_PARAM(bi); fpi = NULL; }  
00656 
00657     // accesses methods & props in the interface
00658     Value*  _get_property(Value* prop);
00659     Value*  _set_property(Value* prop, Value* val);
00660 
00661     Value*  get_property(Value** arg_list, int count);
00662     Value*  set_property(Value** arg_list, int count);
00663 };
00664 
00665 // StaticInterfaceMethod - wraps an FPStaticMethodInterfaceValue and its target object for property-based calls
00666 class StaticInterfaceMethod : public InterfaceFunction
00667 {
00668 private:
00669                 StaticInterfaceMethod(FPStaticMethodInterfaceValue* fpiv, FPFunctionDef* fd);
00670     static      StaticInterfaceMethod* interface_method_cache[FPS_CACHE_SIZE];
00671     friend void Collectable::gc();
00672     friend void Collectable::mark();
00673 public:
00674     FPStaticMethodInterfaceValue* fpiv;
00675 
00676     static ScripterExport StaticInterfaceMethod* intern(FPStaticMethodInterfaceValue* fpiv, FPFunctionDef* fd);
00677                 ~StaticInterfaceMethod();
00678 
00679                 def_generic ( isDeleted,            "isDeleted");   // LAM: 11/23/01 - added - doesn't break SDK
00680                 use_generic( eq,                    "=" );          // LAM: 11/23/01 - added - doesn't break SDK
00681                 use_generic( ne,                    "!=" );         // LAM: 11/23/01 - added - doesn't break SDK
00682     void        collect() { delete this; }
00683     void        gc_trace();
00684 
00685     Value*      apply(Value** arglist, int count, CallContext* cc=NULL);
00686 };
00687