Starting from 2021-07-01, all LRZ GitLab users will be required to explicitly accept the GitLab Terms of Service. Please see the detailed information at https://doku.lrz.de/display/PUBLIC/GitLab and make sure that your projects conform to the requirements.

scopedtypeddata.h 4.11 KB
Newer Older
1 2 3 4
// ================================================================================================
// 
// This file is part of the CAMPVis Software Framework.
// 
5
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
6 7
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
//      Chair for Computer Aided Medical Procedures
8 9
//      Technische Universitaet Muenchen
//      Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
10
// 
11 12
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
// 
13 14 15 16
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 
// except in compliance with the License. You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0
17
// 
18 19 20 21
// Unless required by applicable law or agreed to in writing, software distributed under the 
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
// either express or implied. See the License for the specific language governing permissions 
// and limitations under the License.
22 23 24 25 26 27
// 
// ================================================================================================

#ifndef SCOPEDTYPEDDATA_H__
#define SCOPEDTYPEDDATA_H__

28
#include "cgt/logmanager.h"
29 30
#include "core/datastructures/datacontainer.h"

31 32
#include <typeinfo>

33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
namespace campvis {

    /**
     * Proxy class for scoped strongly-typed access to the data of a DataContainer.
     * From the outside ScopedTypedData<T> behaves exactly like a const T*, but internally it preserves the
     * reference counting of a DataHandle. Use this class when you want temporary access to a strongly-typed
     * data item in a DataContainer but don't want to to the dynamic_cast yourself.
     *
     * \tparam  T   Base class of the DataHandle data to test for
     */
    template<typename T>
    struct ScopedTypedData {
        /**
         * Creates a new DataHandle to the data item with the key \a name in \a dc, that behaves like a T*.
         * \param   dc      DataContainer to grab data from
         * \param   name    Key of the DataHandle to search for
49
         * \param   silent  Flag whether debug messages when no matching data is found should be silenced (defaults to false).
50
         */
51
        ScopedTypedData(const DataContainer& dc, const std::string& name, bool silent = false)
52 53 54 55 56
            : dh(dc.getData(name))
            , data(0)
        {
            if (dh.getData() != 0) {
                data = dynamic_cast<const T*>(dh.getData());
57 58 59 60
                if (data == 0) {
                    if (!silent)
                        LDEBUGC("CAMPVis.core.ScopedTypedData", "Found DataHandle with id '" << name << "', but it is of wrong type (" << typeid(*dh.getData()).name() << " instead of " << typeid(T).name() << ").");
                    
61
                    dh = DataHandle(0);
62 63 64 65 66
                }
            }
            else {
                if (! silent)
                    LDEBUGC("CAMPVis.core.ScopedTypedData", "Could not find a DataHandle with id '" << name << "' in DataContainer '" << dc.getName() << "'.");
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
            }
        };

        /**
         * Implicit conversion operator to const T*.
         * \return  The data in the DataHandle, may be 0 when no DataHandle was found, or the data is of the wrong type.
         */
        operator const T*() {
            return data;
        }

        /**
         * Implicit arrow operator to const T*.
         * \return  The data in the DataHandle, may be 0 when no DataHandle was found, or the data is of the wrong type.
         */
        const T* operator->() const {
            return data;
        }

        /**
         * Gets the DataHandle.
         * \return dh
         */
90
        DataHandle getDataHandle() const {
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
            return dh;
        }

    private:
        /// Not copy-constructable
        ScopedTypedData(const ScopedTypedData& rhs);
        /// Not assignable
        ScopedTypedData& operator=(const ScopedTypedData& rhs);

        DataHandle dh;      ///< DataHandle
        const T* data;      ///< strongly-typed pointer to data, may be 0
    };

}

#endif // SCOPEDTYPEDDATA_H__