object.h
Go to the documentation of this file.
00001 //=================================================================================================
00002 // Copyright (c) 2012, Johannes Meyer, TU Darmstadt
00003 // All rights reserved.
00004 
00005 // Redistribution and use in source and binary forms, with or without
00006 // modification, are permitted provided that the following conditions are met:
00007 //     * Redistributions of source code must retain the above copyright
00008 //       notice, this list of conditions and the following disclaimer.
00009 //     * Redistributions in binary form must reproduce the above copyright
00010 //       notice, this list of conditions and the following disclaimer in the
00011 //       documentation and/or other materials provided with the distribution.
00012 //     * Neither the name of the Flight Systems and Automatic Control group,
00013 //       TU Darmstadt, nor the names of its contributors may be used to
00014 //       endorse or promote products derived from this software without
00015 //       specific prior written permission.
00016 
00017 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00018 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00019 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00020 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
00021 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00022 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00023 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00024 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00026 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027 //=================================================================================================
00028 
00029 #ifndef ROSMATLAB_OBJECT_H
00030 #define ROSMATLAB_OBJECT_H
00031 
00032 #include <rosmatlab/exception.h>
00033 #include <boost/shared_ptr.hpp>
00034 #include "mex.h"
00035 
00036 #include <stdint.h>
00037 
00038 namespace rosmatlab {
00039 
00040 namespace {
00041   struct null_deleter {
00042     void operator()(void const *) const {}
00043   };
00044 }
00045 
00046 template <class Type>
00047 class Object
00048 {
00049 public:
00050   typedef boost::shared_ptr<Type> Ptr;
00051 
00052   Object() { construct(); }
00053   Object(Type *instance) { *this = instance; construct(); }
00054   Object(const Ptr &instance) { *this = instance; construct(); }
00055   Object(const Object &other) { *this = other; construct(); }
00056   virtual ~Object() { if (handle_) mxDestroyArray(handle_); }
00057 
00058   const Ptr &instance() const { return instance_; }
00059   mxArray *handle() const { return handle_; }
00060 
00061   Type* get() { return instance_.get(); }
00062   const Type* get() const { return instance_.get(); }
00063   Type &operator*() { return *instance_; }
00064   const Type &operator*() const { return *instance_; }
00065 
00066   Object<Type> &operator=(const Object &other) {
00067     return *this = other.instance_;
00068   }
00069 
00070   Object<Type> &operator=(Type *instance) {
00071     return *this = Ptr(instance, null_deleter());
00072   }
00073 
00074   Object<Type> &operator=(const Ptr &instance) {
00075     instance_ = instance;
00076     return *this;
00077   }
00078 
00079   static Object<Type> *byHandle(const mxArray *handle) {
00080     const mxArray *ptr = 0;
00081     if (!handle) return 0;
00082     // mexPrintf("Searching for object of type %s (class %s)...\n", typeid(Type).name(), mxGetClassName(handle));
00083     if (mxIsClass(handle, class_name_)) {
00084       ptr = mxGetProperty(handle, 0, "handle");
00085     } else if (mxIsStruct(handle)) {
00086       ptr = mxGetField(handle, 0, "handle");
00087     } else if (mxIsDouble(handle)) {
00088       ptr = handle;
00089     }
00090     if (!ptr || !mxIsDouble(ptr) || !mxGetNumberOfElements(ptr) > 0 || !mxGetPr(ptr)) throw Exception("invalid handle");
00091 
00092     Object<Type> *object = reinterpret_cast<Object<Type> *>(static_cast<uint64_t>(*mxGetPr(ptr)));
00093     return object;
00094   }
00095 
00096 private:
00097   boost::shared_ptr<Type> instance_;
00098   mxArray *handle_;
00099   static const char *class_name_;
00100 
00101   void construct() {
00102     handle_ = mxCreateDoubleScalar(reinterpret_cast<uint64_t>(this));
00103     mexMakeArrayPersistent(handle_);
00104     assert(byHandle(handle()) == this);
00105   }
00106 };
00107 
00108 template <class Type>
00109 Type *getObject(const mxArray *handle) {
00110   Object<Type> *object = Object<Type>::byHandle(handle);
00111   if (!object) return 0;
00112   return object->get();
00113 }
00114 
00115 } // namespace rosmatlab
00116 
00117 #endif // ROSMATLAB_OBJECT_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


rosmatlab
Author(s): Johannes Meyer
autogenerated on Tue Jan 8 2013 17:31:00