summaryrefslogtreecommitdiff
path: root/include/gras/detail/block.hpp
blob: 9dccb2276d01e53d5004f9495ceba1b614b28158 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright (C) by Josh Blum. See LICENSE.txt for licensing information.

#ifndef INCLUDED_GRAS_DETAIL_BLOCK_HPP
#define INCLUDED_GRAS_DETAIL_BLOCK_HPP

#include <typeinfo>

namespace gras
{

struct GRAS_API PropertyRegistry
{
    PropertyRegistry(void);
    virtual ~PropertyRegistry(void);
    virtual void set(const PMCC &) = 0;
    virtual PMCC get(void) = 0;
    virtual const std::type_info &type(void) const = 0;
};

template <typename ClassType, typename ValueType>
class PropertyRegistryImpl : public PropertyRegistry
{
public:
    PropertyRegistryImpl(
        ClassType *my_class,
        ValueType(ClassType::*getter)(void),
        void(ClassType::*setter)(const ValueType &)
    ):
        _my_class(my_class),
        _getter(getter),
        _setter(setter)
    {}
    virtual ~PropertyRegistryImpl(void){}

    void set(const PMCC &value)
    {
        (_my_class->*_setter)(value.safe_as<ValueType>());
    }

    PMCC get(void)
    {
        return PMC_M((_my_class->*_getter)());
    }

    const std::type_info &type(void) const
    {
        return typeid(ValueType);
    }

private:
    ClassType *_my_class;
    ValueType(ClassType::*_getter)(void);
    void(ClassType::*_setter)(const ValueType &);
};

/*!
 * The following functions implement the templated methods in Block
 */

template <typename ClassType, typename ValueType>
inline void Block::register_getter(
    const std::string &key,
    ValueType(ClassType::*get)(void)
)
{
    ClassType *obj = dynamic_cast<ClassType *>(this);
    void *pr = new PropertyRegistryImpl<ClassType, ValueType>(obj, get, NULL);
    this->_register_getter(key, pr);
}

template <typename ClassType, typename ValueType>
inline void Block::register_setter(
    const std::string &key,
    void(ClassType::*set)(const ValueType &)
)
{
    ClassType *obj = dynamic_cast<ClassType *>(this);
    void *pr = new PropertyRegistryImpl<ClassType, ValueType>(obj, NULL, set);
    this->_register_setter(key, pr);
}

template <typename ValueType>
inline void Block::set(const std::string &key, const ValueType &value)
{
    this->_set_property(key, PMC_M(value));
}

template <typename ValueType>
inline void Block::get(const std::string &key, ValueType &value)
{
    value = this->_get_property(key).safe_as<ValueType>();
}

template <typename ValueType>
inline ValueType Block::get(const std::string &key)
{
    return this->_get_property(key).safe_as<ValueType>();
}

template <typename ValueType>
inline void Block::post_output_msg(const size_t i, const ValueType &value)
{
    this->_post_output_msg(i, PMC_M(value));
}

template <>
inline void Block::post_output_msg(const size_t i, const PMCC &value)
{
    this->_post_output_msg(i, value);
}

template <>
inline void Block::post_output_msg(const size_t i, const PMC &value)
{
    this->_post_output_msg(i, value);
}

template <typename ValueType>
inline void Block::post_input_msg(const size_t i, const ValueType &value)
{
    this->_post_input_msg(i, PMC_M(value));
}

template <>
inline void Block::post_input_msg(const size_t i, const PMCC &value)
{
    this->_post_input_msg(i, value);
}

template <>
inline void Block::post_input_msg(const size_t i, const PMC &value)
{
    this->_post_input_msg(i, value);
}

} //namespace gras

#endif /*INCLUDED_GRAS_DETAIL_BLOCK_HPP*/