Previous 199869 Revisions Next

r18529 Monday 15th October, 2012 at 07:35:25 UTC by Aaron Giles
A little more unification of delegate types.
[src/emu]delegate.c delegate.h

trunk/src/emu/delegate.c
r18528r18529
5353//  return the actual final code pointer
5454//-------------------------------------------------
5555
56delegate_generic_function delegate_internal_mfp::convert_to_generic(delegate_generic_class *&object) const
56delegate_generic_function delegate_mfp::convert_to_generic(delegate_generic_class *&object) const
5757{
5858   // apply the "this" delta to the object first
5959   object = reinterpret_cast<delegate_generic_class *>(reinterpret_cast<UINT8 *>(object) + m_this_delta);
trunk/src/emu/delegate.h
r18528r18529
133133//  HELPER CLASSES
134134//**************************************************************************
135135
136// generic function type
137typedef void (*delegate_generic_function)();
138
139
136140// ======================> generic_class
137141
138142// define a dummy generic class that is just straight single-inheritance
r18528r18529
233237
234238
235239//**************************************************************************
240//  DELEGATE MEMBER FUNCTION POINTER WRAPPERS
241//**************************************************************************
242
243#if (USE_DELEGATE_TYPE == DELEGATE_TYPE_COMPATIBLE)
244
245// ======================> delegate_mfp
246
247// delegate_mfp is a class that wraps a generic member function pointer
248// in a static buffer, and can effectively recast itself back for later use;
249// it hides some of the gross details involved in copying artibtrary member
250// function pointers around
251struct delegate_mfp
252{
253   // default constructor
254   delegate_mfp() { memset(&m_rawdata, 0, sizeof(m_rawdata)); }
255   
256   // copy constructor
257   delegate_mfp(const delegate_mfp &src)
258      : m_rawdata(src.m_rawdata) { }
259
260   // construct from any member function pointer
261   template<typename _FunctionType>
262   delegate_mfp(_FunctionType mfp)
263   {
264      assert(sizeof(mfp) <= sizeof(m_rawdata));
265      memset(&m_rawdata, 0, sizeof(m_rawdata));
266      *reinterpret_cast<_FunctionType *>(&m_rawdata) = mfp;
267   }
268
269   // assignment operator
270   delegate_mfp &operator=(const delegate_mfp &src)
271   {
272      if (this != &src)
273         m_rawdata = src.m_rawdata;
274      return *this;
275   }
276
277   // comparison operator
278   bool operator==(const delegate_mfp &rhs) const
279   {
280      return (memcmp(&m_rawdata, &rhs.m_rawdata, sizeof(m_rawdata)) == 0);
281   }
282
283   // isnull checker
284   bool isnull() const
285   {
286      for (int index = 0; index < ARRAY_LENGTH(m_rawdata.data); index++)
287         if (m_rawdata.data[index] != 0)
288            return false;
289      return true;
290   }
291
292   // convert back to a member function pointer
293   template<class _FunctionType>
294   _FunctionType &mfp() const { return *reinterpret_cast<_FunctionType *>(&m_rawdata); }
295
296   // for MSVC maximum size is one pointer, plus 3 ints;
297   // all other implementations seem to be smaller
298   static const int MAX_MFP_SIZE = sizeof(void *) + 3 * sizeof(int);
299
300   // raw buffer to hold the copy of the function pointer
301   mutable struct { int data[(MAX_MFP_SIZE + sizeof(int) - 1) / sizeof(int)]; } m_rawdata;
302};
303
304#elif (USE_DELEGATE_TYPE == DELEGATE_TYPE_INTERNAL)
305
306// ======================> delegate_mfp
307
308// struct describing the contents of a member function pointer
309struct delegate_mfp
310{
311   // default constructor
312   delegate_mfp()
313      : m_function(0),
314        m_this_delta(0) { }
315
316   // copy constructor
317   delegate_mfp(const delegate_mfp &src)
318      : m_function(src.m_function),
319        m_this_delta(src.m_this_delta) { }
320
321   // construct from any member function pointer
322   template<typename _FunctionPtr>
323   delegate_mfp(_FunctionPtr mfp)
324   {
325      assert(sizeof(mfp) == sizeof(*this));
326      *reinterpret_cast<_FunctionPtr *>(this) = mfp;
327   }
328
329   // assignment operator
330   delegate_mfp &operator=(const delegate_mfp &src)
331   {
332      if (this != &src)
333      {
334         m_function = src.m_function;
335         m_this_delta = src.m_this_delta;
336      }
337      return *this;
338   }
339
340   // comparison operator
341   bool operator==(const delegate_mfp &rhs) const
342   {
343      return (m_function == rhs.m_function && m_this_delta == rhs.m_this_delta);
344   }
345   
346   // isnull checker
347   bool isnull() const { return (m_function == 0); }
348
349   // extract the generic function and adjust the object pointer
350   delegate_generic_function convert_to_generic(delegate_generic_class *&object) const;
351
352   // actual state
353   FPTR               m_function;         // first item can be one of two things:
354                                    //    if even, it's a pointer to the function
355                                    //    if odd, it's the byte offset into the vtable
356   int                m_this_delta;      // delta to apply to the 'this' pointer
357};
358
359#endif
360
361
362//**************************************************************************
236363//  COMMON DELEGATE BASE CLASS
237364//**************************************************************************
238365
r18528r18529
245372   typedef delegate_generic_class *(*late_bind_func)(delegate_late_bind &object);
246373
247374   // construction
248   delegate_common_base(const char *name = NULL, late_bind_func latebinder = NULL, delegate_generic_class *object = NULL)
375   delegate_common_base(const char *name = NULL, late_bind_func latebinder = NULL, delegate_generic_function funcptr = NULL)
249376      : m_name(name),
250        m_object(object),
251        m_latebinder(latebinder) { }
377        m_object(NULL),
378        m_latebinder(latebinder),
379        m_raw_function(funcptr) { }
252380
381   template<typename _FunctionPtr>
382   delegate_common_base(const char *name, late_bind_func latebinder, _FunctionPtr funcptr)
383      : m_name(name),
384        m_object(NULL),
385        m_latebinder(latebinder),
386        m_raw_function(NULL),
387        m_raw_mfp(funcptr) { }
388
389   // copy constructor
253390   delegate_common_base(const delegate_common_base &src)
254391      : m_name(src.m_name),
255392        m_object(src.m_object),
256        m_latebinder(src.m_latebinder) { }
393        m_latebinder(src.m_latebinder),
394        m_raw_function(src.m_raw_function),
395        m_raw_mfp(src.m_raw_mfp) { }
257396
397   // copy helper
398   void copy(const delegate_common_base &src)
399   {
400      m_name = src.m_name;
401      m_object = src.m_object;
402      m_latebinder = src.m_latebinder;
403      m_raw_function = src.m_raw_function;
404      m_raw_mfp = src.m_raw_mfp;
405   }
406   
258407public:
259408   // getters
260409   bool has_object() const { return (m_object != NULL); }
261410   const char *name() const { return m_name; }
411   
412   // helpers
413   bool isnull() const { return (m_raw_function == NULL && m_raw_mfp.isnull()); }
414   bool is_mfp() const { return !m_raw_mfp.isnull(); }
262415
416   // comparison helper
417   bool operator==(const delegate_common_base &rhs) const
418   {
419      return (m_object == rhs.m_object && m_raw_function == rhs.m_raw_function && m_raw_mfp == rhs.m_raw_mfp);
420   }
421
263422protected:
264423   // late binding helper
265424   template<class _FunctionClass>
r18528r18529
275434   const char *            m_name;            // name string
276435   delegate_generic_class *   m_object;         // pointer to the post-cast object
277436   late_bind_func            m_latebinder;      // late binding helper
437   delegate_generic_function   m_raw_function;      // raw static function pointer
438   delegate_mfp            m_raw_mfp;         // raw member function pointer
278439};
279440
280441
r18528r18529
285446
286447#if (USE_DELEGATE_TYPE == DELEGATE_TYPE_COMPATIBLE)
287448
288// ======================> delegate_raw_mfp
289
290// delegate_raw_mfp is a class that wraps a generic member function pointer
291// in a static buffer, and can effectively recast itself back for later use;
292// it hides some of the gross details involved in copying artibtrary member
293// function pointers around
294struct delegate_raw_mfp
295{
296   // for MSVC maximum size is one pointer, plus 3 ints
297   static const int MAX_MFP_SIZE = sizeof(void *) + 3 * sizeof(int);
298
299   // default and copy constructors
300   delegate_raw_mfp() { memset(&m_rawdata, 0, sizeof(m_rawdata)); }
301   delegate_raw_mfp(const delegate_raw_mfp &src) : m_rawdata(src.m_rawdata) { }
302
303   // construct from any member function pointer
304   template<typename _FunctionType>
305   delegate_raw_mfp(_FunctionType mfp)
306   {
307      assert(sizeof(mfp) <= sizeof(m_rawdata));
308      memset(&m_rawdata, 0, sizeof(m_rawdata));
309      *reinterpret_cast<_FunctionType *>(&m_rawdata) = mfp;
310   }
311
312   // assignment operator
313   delegate_raw_mfp &operator=(const delegate_raw_mfp &src)
314   {
315      if (this != &src)
316         m_rawdata = src.m_rawdata;
317      return *this;
318   }
319
320   // comparison operator
321   bool operator==(const delegate_raw_mfp &rhs) const
322   {
323      return (memcmp(&m_rawdata, &rhs.m_rawdata, sizeof(m_rawdata)) == 0);
324   }
325
326   // convert back to a member function pointer
327   template<class _FunctionType>
328   _FunctionType &mfp() const { return *reinterpret_cast<_FunctionType *>(&m_rawdata); }
329
330   // raw buffer to hold the copy of the function pointer
331   mutable struct { UINT8 bytes[MAX_MFP_SIZE]; } m_rawdata;
332};
333
334
335449// ======================> delegate_base
336450
337451// general delegate class template supporting up to 4 parameters
r18528r18529
358472   delegate_base(const delegate_base &src)
359473      : delegate_common_base(src),
360474        m_function(src.m_function),
361        m_callobject(src.is_mfp() ? reinterpret_cast<delegate_generic_class *>(this) : src.m_object),
362        m_rawfunction(src.m_rawfunction) { }
475        m_callobject(src.is_mfp() ? reinterpret_cast<delegate_generic_class *>(this) : src.m_object) { }
363476
364477   // copy constructor with late bind
365478   delegate_base(const delegate_base &src, delegate_late_bind &object)
366479      : delegate_common_base(src),
367480        m_function(src.m_function),
368        m_callobject(src.is_mfp() ? reinterpret_cast<delegate_generic_class *>(this) : src.m_object),
369        m_rawfunction(src.m_rawfunction)
481        m_callobject(src.is_mfp() ? reinterpret_cast<delegate_generic_class *>(this) : src.m_object)
370482   {
371483      late_bind(object);
372484   }
r18528r18529
374486   // construct from member function with object pointer
375487   template<class _FunctionClass>
376488   delegate_base(typename traits<_FunctionClass>::member_func_type funcptr, const char *name, _FunctionClass *object)
377      : delegate_common_base(name, &late_bind_helper<_FunctionClass>),
489      : delegate_common_base(name, &late_bind_helper<_FunctionClass>, funcptr),
378490        m_function(&delegate_base::method_stub<_FunctionClass>),
379        m_callobject(reinterpret_cast<delegate_generic_class *>(this)),
380        m_rawfunction(funcptr)
491        m_callobject(reinterpret_cast<delegate_generic_class *>(this))
381492   {
382493      bind(reinterpret_cast<delegate_generic_class *>(object));
383494   }
r18528r18529
385496   // construct from static function with object pointer
386497   template<class _FunctionClass>
387498   delegate_base(typename traits<_FunctionClass>::static_func_type funcptr, const char *name, _FunctionClass *object)
388      : delegate_common_base(name, &late_bind_helper<_FunctionClass>),
499      : delegate_common_base(name, &late_bind_helper<_FunctionClass>, reinterpret_cast<delegate_generic_function>(funcptr)),
389500        m_function(reinterpret_cast<generic_static_func>(funcptr)),
390501        m_callobject(NULL)
391502   {
r18528r18529
395506   // construct from static reference function with object pointer
396507   template<class _FunctionClass>
397508   delegate_base(typename traits<_FunctionClass>::static_ref_func_type funcptr, const char *name, _FunctionClass *object)
398      : delegate_common_base(name, &late_bind_helper<_FunctionClass>),
509      : delegate_common_base(name, &late_bind_helper<_FunctionClass>, reinterpret_cast<delegate_generic_function>(funcptr)),
399510        m_function(reinterpret_cast<generic_static_func>(funcptr)),
400511        m_callobject(NULL)
401512   {
r18528r18529
407518   {
408519      if (this != &src)
409520      {
410         m_name = src.m_name;
411         m_object = src.m_object;
521         delegate_common_base::copy(src);
412522         m_callobject = src.is_mfp() ? reinterpret_cast<delegate_generic_class *>(this) : src.m_object;
413523         m_function = src.m_function;
414         m_rawfunction = src.m_rawfunction;
415         m_latebinder = src.m_latebinder;
416524      }
417525      return *this;
418526   }
419527
420   // comparison operator
421   bool operator==(const delegate_base &rhs) const
422   {
423      return (m_object == rhs.m_object && m_function == rhs.m_function && m_rawfunction == rhs.m_rawfunction);
424   }
425
426   // getters
427   bool isnull() const { return (m_function == NULL); }
428
429528   // call the function
430529   _ReturnType operator()() const { return (*m_function)(m_callobject); }
431530   _ReturnType operator()(_P1Type p1) const { return (*m_function)(m_callobject, p1); }
r18528r18529
454553    {
455554       typedef _ReturnType (_FunctionClass::*mfptype)();
456555       delegate_base *_this = reinterpret_cast<delegate_base *>(object);
457       mfptype &mfp = _this->m_rawfunction.mfp<mfptype>();
556       mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>();
458557       return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)();
459558    }
460559
r18528r18529
463562    {
464563       typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1);
465564       delegate_base *_this = reinterpret_cast<delegate_base *>(object);
466       mfptype &mfp = _this->m_rawfunction.mfp<mfptype>();
565       mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>();
467566       return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1);
468567    }
469568
r18528r18529
472571    {
473572       typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2);
474573       delegate_base *_this = reinterpret_cast<delegate_base *>(object);
475       mfptype &mfp = _this->m_rawfunction.mfp<mfptype>();
574       mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>();
476575       return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1, p2);
477576    }
478577
r18528r18529
481580    {
482581       typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2, _P3Type p3);
483582       delegate_base *_this = reinterpret_cast<delegate_base *>(object);
484       mfptype &mfp = _this->m_rawfunction.mfp<mfptype>();
583       mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>();
485584       return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1, p2, p3);
486585    }
487586
r18528r18529
490589    {
491590       typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4);
492591       delegate_base *_this = reinterpret_cast<delegate_base *>(object);
493       mfptype &mfp = _this->m_rawfunction.mfp<mfptype>();
592       mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>();
494593       return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1, p2, p3, p4);
495594    }
496595
r18528r18529
499598    {
500599       typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5);
501600       delegate_base *_this = reinterpret_cast<delegate_base *>(object);
502       mfptype &mfp = _this->m_rawfunction.mfp<mfptype>();
601       mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>();
503602       return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1, p2, p3, p4, p5);
504603    }
505604
506605   // internal state
507606   generic_static_func         m_function;         // generic static function pointer
508607   delegate_generic_class *   m_callobject;      // pointer to the object used for calling
509   delegate_raw_mfp         m_rawfunction;      // copy of raw MFP
510608};
511609
512610#endif
r18528r18529
518616
519617#if (USE_DELEGATE_TYPE == DELEGATE_TYPE_INTERNAL)
520618
521// a generic function pointer type and a generic member function pointer type
522typedef void (*delegate_generic_function)();
523
524// struct describing the contents of a member function pointer
525struct delegate_internal_mfp
526{
527   // default constructor
528   delegate_internal_mfp()
529      : m_function(0),
530        m_this_delta(0) { }
531
532   // copy constructor
533   delegate_internal_mfp(const delegate_internal_mfp &src)
534      : m_function(src.m_function),
535        m_this_delta(src.m_this_delta) { }
536
537   // construct from any member function pointer
538   template<typename _FunctionPtr>
539   delegate_internal_mfp(_FunctionPtr funcptr)
540   {
541      assert(sizeof(funcptr) == sizeof(*this));
542      *reinterpret_cast<_FunctionPtr *>(this) = funcptr;
543   }
544
545   // assignment operator
546   delegate_internal_mfp &operator=(const delegate_internal_mfp &src)
547   {
548      if (this != &src)
549      {
550         m_function = src.m_function;
551         m_this_delta = src.m_this_delta;
552      }
553      return *this;
554   }
555
556   // comparison operator
557   bool operator==(const delegate_internal_mfp &rhs) const
558   {
559      return (m_function == rhs.m_function && m_this_delta == rhs.m_this_delta);
560   }
561
562   // extract the generic function and adjust the object pointer
563   delegate_generic_function convert_to_generic(delegate_generic_class *&object) const;
564
565   // actual state
566   FPTR               m_function;         // first item can be one of two things:
567                                    //    if even, it's a pointer to the function
568                                    //    if odd, it's the byte offset into the vtable
569   int                m_this_delta;      // delta to apply to the 'this' pointer
570};
571
572
573619// ======================> delegate_base
574620
575621template<typename _ReturnType, typename _P1Type = _noparam, typename _P2Type = _noparam, typename _P3Type = _noparam, typename _P4Type = _noparam, typename _P5Type = _noparam>
r18528r18529
593639   // copy constructor
594640   delegate_base(const delegate_base &src)
595641      : delegate_common_base(src),
596        m_function(src.m_function),
597        m_rawfunction(src.m_rawfunction) { }
642        m_function(src.m_function) { }
598643
599644   // copy constructor with late bind
600645   delegate_base(const delegate_base &src, delegate_late_bind &object)
601646      : delegate_common_base(src),
602        m_function(src.m_function),
603        m_rawfunction(src.m_rawfunction)
647        m_function(src.m_function)
604648   {
605649      late_bind(object);
606650   }
r18528r18529
608652   // construct from member function with object pointer
609653   template<class _FunctionClass>
610654   delegate_base(typename traits<_FunctionClass>::member_func_type funcptr, const char *name, _FunctionClass *object)
611      : delegate_common_base(name, &late_bind_helper<_FunctionClass>),
612        m_function(NULL),
613        m_rawfunction(funcptr)
655      : delegate_common_base(name, &late_bind_helper<_FunctionClass>, funcptr),
656        m_function(NULL)
614657   {
615658      bind(reinterpret_cast<delegate_generic_class *>(object));
616659   }
r18528r18529
618661   // construct from static function with object pointer
619662   template<class _FunctionClass>
620663   delegate_base(typename traits<_FunctionClass>::static_func_type funcptr, const char *name, _FunctionClass *object)
621      : delegate_common_base(name, &late_bind_helper<_FunctionClass>),
664      : delegate_common_base(name, &late_bind_helper<_FunctionClass>, reinterpret_cast<delegate_generic_function>(funcptr)),
622665        m_function(reinterpret_cast<generic_static_func>(funcptr))
623666   {
624667      bind(reinterpret_cast<delegate_generic_class *>(object));
r18528r18529
627670   // construct from static reference function with object pointer
628671   template<class _FunctionClass>
629672   delegate_base(typename traits<_FunctionClass>::static_ref_func_type funcptr, const char *name, _FunctionClass *object)
630      : delegate_common_base(name, &late_bind_helper<_FunctionClass>),
673      : delegate_common_base(name, &late_bind_helper<_FunctionClass>, reinterpret_cast<delegate_generic_function>(funcptr)),
631674        m_function(reinterpret_cast<generic_static_func>(funcptr))
632675   {
633676      bind(reinterpret_cast<delegate_generic_class *>(object));
r18528r18529
638681   {
639682      if (this != &src)
640683      {
641         m_name = src.m_name;
642         m_object = src.m_object;
684         delegate_common_base::copy(src);
643685         m_function = src.m_function;
644         m_rawfunction = src.m_rawfunction;
645         m_latebinder = src.m_latebinder;
646686      }
647687      return *this;
648688   }
649689
650   // comparison operator
651   bool operator==(const delegate_base &rhs) const
652   {
653      return (m_object == rhs.m_object && m_function == rhs.m_function && m_rawfunction == rhs.m_rawfunction);
654   }
655
656   // getters
657   bool isnull() const { return (m_function == NULL && m_rawfunction.m_function == 0); }
658
659690   // call the function
660691   _ReturnType operator()() const { return (*m_function)(m_object); }
661692   _ReturnType operator()(_P1Type p1) const { return (*m_function)(m_object, p1); }
r18528r18529
672703   void bind(delegate_generic_class *object)
673704   {
674705      m_object = object;
675      if (m_object != NULL && m_rawfunction.m_function != 0)
676         m_function = reinterpret_cast<generic_static_func>(m_rawfunction.convert_to_generic(m_object));
706      if (m_object != NULL && is_mfp())
707         m_function = reinterpret_cast<generic_static_func>(m_raw_mfp.convert_to_generic(m_object));
677708   }
678709
679710   // internal state
680711   generic_static_func         m_function;         // generic static function pointer
681   delegate_internal_mfp      m_rawfunction;      // raw member function definition
682712};
683713
684714#endif

Previous 199869 Revisions Next


© 1997-2024 The MAME Team