[dali_1.1.2] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / common / message-buffer.h
1 #ifndef __DALI_INTERNAL_MESSAGE_BUFFER_H__
2 #define __DALI_INTERNAL_MESSAGE_BUFFER_H__
3
4 /*
5  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <cstddef>
23
24 // INTERNAL INCLUDES
25 #include <dali/devel-api/common/mutex.h>
26
27 namespace Dali
28 {
29
30 namespace Internal
31 {
32
33 /**
34  * Utility class to reserve a buffer for storing messages.
35  */
36 class MessageBuffer
37 {
38 public:
39   typedef std::ptrdiff_t WordType;
40
41   /**
42    * Create a new MessageBuffer
43    * @param[in] The smallest capacity which the buffer will allocate, with respect to the size of type "char".
44    * @note The buffer will not allocate memory until the first call to ReserveMessageSlot().
45    */
46   MessageBuffer( std::size_t initialCapacity );
47
48   /**
49    * Non-virtual destructor; not suitable as a base class
50    */
51   ~MessageBuffer();
52
53   /**
54    * Reserve space for another message in the buffer.
55    * @pre size is greater than zero.
56    * @param[in] size The message size with respect to the size of type "char".
57    * @return A pointer to the address allocated for the message, aligned to a word boundary
58    */
59   unsigned int* ReserveMessageSlot( std::size_t size );
60
61   /**
62    * Query the capacity of the message buffer.
63    * @return The capacity with respect to the size of type "char".
64    */
65   std::size_t GetCapacity() const;
66
67   /**
68    * Used to iterate though the messages in the buffer.
69    */
70   class Iterator
71   {
72   public:
73
74     // Constructor
75     Iterator(WordType* current);
76
77     // Inlined for performance
78     bool IsValid()
79     {
80       // Valid until end marker has been found
81       return 0 != mMessageSize;
82     }
83
84     // Inlined for performance
85     WordType* Get()
86     {
87       return ( 0 != mMessageSize ) ? mCurrent : NULL;
88     }
89
90     // Inlined for performance
91     void Next()
92     {
93       // Jump to next object and read size
94       mCurrent += mMessageSize;
95       mMessageSize = *mCurrent++;
96     }
97
98     // Copy constructor
99     Iterator(const Iterator& copy);
100
101   private:
102
103     // Undefined
104     Iterator& operator=(const Iterator& rhs);
105
106   private:
107
108     WordType* mCurrent;
109     std::size_t mMessageSize;
110   };
111
112   /**
113    * Returns an iterator to the first message in the buffer.
114    * There is no past-the-end iterator; use Iterator::IsValid() to determine when the has been reached.
115    * @note Adding more messages with ReserveMessageSlot() may corrupt this iterator.
116    * @return The iterator.
117    */
118   Iterator Begin() const;
119
120   /**
121    * Sets the size of the buffer to zero (does not deallocate memory)
122    */
123   void Reset();
124
125 private:
126
127   // Undefined
128   MessageBuffer(const MessageBuffer&);
129
130   // Undefined
131   MessageBuffer& operator=(const MessageBuffer& rhs);
132
133   /**
134    * Helper to increase the capacity of the buffer.
135    * @pre The newCapacity is greater than mCapacity.
136    * @param[in] The newCapacity
137    */
138   void IncreaseCapacity( std::size_t newCapacity );
139
140 private:
141
142   std::size_t mInitialCapacity; ///< The capacity to allocate during first call to ReserveMessageSlot
143
144   WordType* mData;     ///< The data allocated for the message buffer
145   WordType* mNextSlot; ///< The next free location in the buffer
146
147   std::size_t mCapacity; ///< The memory allocated with respect to sizeof(WordType)
148   std::size_t mSize;     ///< The memory reserved for messages with respect to sizeof(WordType)
149   Dali::Mutex mMutex;    ///< Mutex to ensure correct access locking
150 };
151
152 } // namespace Internal
153
154 } // namespace Dali
155
156 #endif // __DALI_INTERNAL_MESSAGE_BUFFER_H__