generic_class.h

Go to the documentation of this file.
00001 //**************************************************************************/
00002 // Copyright (c) 1998-2008 Autodesk, Inc.
00003 // All rights reserved.
00004 // 
00005 // These coded instructions, statements, and computer programs contain
00006 // unpublished proprietary information written by Autodesk, Inc., and are
00007 // protected by Federal copyright law. They may not be disclosed to third
00008 // parties or copied or duplicated in any form, in whole or in part, without
00009 // the prior written consent of Autodesk, Inc.
00010 //**************************************************************************/
00011 #pragma once
00012 
00013 
00014 //*! \brief A replacement for the declare_local_generic_class macro shown above.
00015 /*  This macro declares two classes for exposing a type to maxscript. */ 
00016 #define DECLARE_LOCAL_GENERIC_CLASS( _rootclass, _cls )                      \
00017     class _cls##Class : public ValueMetaClass                               \
00018     {                                                                       \
00019     public:                                                                 \
00020         _cls##Class(MCHAR* name);                                          \
00021         void collect();                                                    \
00022     };                                                                      \
00023     extern _cls##Class _cls##_class;                                        \
00024     class _rootclass;                                                       \
00025     typedef Value* (_rootclass::*local_value_vf)(Value**, int);             \
00026     class _cls : public Generic                                             \
00027     {                                                                       \
00028     public:                                                                 \
00029         local_value_vf fn_ptr;                                             \
00030         _cls();                                                            \
00031         _cls(MCHAR* name, local_value_vf fn);                              \
00032         classof_methods (_cls, Generic);                                   \
00033         void collect();                                                    \
00034         Value* apply(Value** arglist, int count, CallContext* cc = NULL);  \
00035     };
00036 
00037 #define DEFINE_LOCAL_GENERIC_CLASS( _rootClass, _cls )                      \
00038     _cls##Class::_cls##Class(MCHAR* name)                                      \
00039             : ValueMetaClass (name)                                          \
00040     {                                                                          \
00041     }                                                                          \
00042     void _cls##Class::collect()                                                \
00043     {                                                                          \
00044         delete this;                                                          \
00045     }                                                                          \
00046                                                                                \
00047     _cls::_cls()                                                               \
00048     {                                                                          \
00049     }                                                                          \
00050     _cls::_cls(MCHAR*fn_name, local_value_vf fn)                                            \
00051     {                                                                           \
00052         tag = &(_cls##_class);                                                      \
00053         fn_ptr = fn;                                                                \
00054         name = save_string(fn_name);                                                    \
00055     }                                                                           \
00056     Value* _cls::apply(Value** arg_list, int count, CallContext* cc)                            \
00057     {                                                                           \
00058         if (thread_local(is_dubugger_thread) && !theMXSDebugger->GetAllowUnsafeMethods())       \
00059             throw DebuggerRuntimeError("Method not available from debugger: ",name);            \
00060         Value*  result = NULL;                                                      \
00061         Value** evald_args;                                                     \
00062         if (count < 1)                                                              \
00063             throw ArgCountError("Generic apply", 1, count);                             \
00064         value_local_array(evald_args, count);                                           \
00065         Value** ap = arg_list;                                                      \
00066         Value** eap = evald_args;                                                   \
00067         for (int i = count; i > 0; i--)                                             \
00068         {                                                                       \
00069             *eap = (*ap)->eval();                                                   \
00070             eap++;                                                              \
00071             ap++;                                                               \
00072         }                                                                       \
00073         if (evald_args[0]->local_base_class() == &_rootClass##_class)                       \
00074             result = (((_rootClass*)evald_args[0])->*fn_ptr)(&evald_args[1], count - 1);        \
00075         else                                                                        \
00076             throw NoMethodError (name, evald_args[0]);                                  \
00077         pop_value_local_array(evald_args);                                              \
00078         return result;                                                              \
00079     }                                                                                              \
00080     void _cls::collect()                                                                           \
00081     {                                                                                              \
00082         delete this;                                                                              \
00083     }                                                                                              \
00084     _cls##Class _cls##_class (#_cls);
00085 
00086 
00087 #define DEFINE_LOCAL_GENERIC_CLASS_DEBUG_OK( _rootClass, _cls )                 \
00088     _cls##Class::_cls##Class(MCHAR* name)                                      \
00089             : ValueMetaClass (name)                                          \
00090     {                                                                          \
00091     }                                                                          \
00092     void _cls##Class::collect()                                                \
00093     {                                                                          \
00094         delete this;                                                          \
00095     }                                                                          \
00096                                                                                \
00097     _cls::_cls()                                                               \
00098     {                                                                          \
00099     }                                                                          \
00100     _cls::_cls(MCHAR*fn_name, local_value_vf fn)                                            \
00101     {                                                                           \
00102         tag = &(_cls##_class);                                                      \
00103         fn_ptr = fn;                                                                \
00104         name = save_string(fn_name);                                                    \
00105         flags3 |= VALUE_FLAGBIT_0;                                                  \
00106     }                                                                           \
00107     Value* _cls::apply(Value** arg_list, int count, CallContext* )                          \
00108     {                                                                           \
00109         Value*  result = NULL;                                                      \
00110         Value** evald_args;                                                     \
00111         if (count < 1)                                                              \
00112             throw ArgCountError("Generic apply", 1, count);                             \
00113         value_local_array(evald_args, count);                                           \
00114         Value** ap = arg_list;                                                      \
00115         Value** eap = evald_args;                                                   \
00116         for (int i = count; i > 0; i--)                                             \
00117         {                                                                       \
00118             *eap = (*ap)->eval();                                                   \
00119             eap++;                                                              \
00120             ap++;                                                               \
00121         }                                                                       \
00122         if (evald_args[0]->local_base_class() == &_rootClass##_class)                       \
00123             result = (((_rootClass*)evald_args[0])->*fn_ptr)(&evald_args[1], count - 1);        \
00124         else                                                                        \
00125             throw NoMethodError (name, evald_args[0]);                                  \
00126         pop_value_local_array(evald_args);                                              \
00127         return result;                                                              \
00128     }                                                                           \
00129     void _cls::collect()                                                                           \
00130     {                                                                                              \
00131         delete this;                                                                              \
00132     }                                                                           \
00133     _cls##Class _cls##_class (#_cls);