Skip to content

Commit c22ded6

Browse files
committed
Merge pull request #57 from christiankerl/refactor_frame_listener
SyncMultiFrameListener changes
2 parents bb19703 + 9cf18f4 commit c22ded6

File tree

3 files changed

+76
-22
lines changed

3 files changed

+76
-22
lines changed

examples/protonect/include/libfreenect2/frame_listener.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#ifndef FRAME_LISTENER_HPP_
2828
#define FRAME_LISTENER_HPP_
2929

30+
#include <cstddef>
31+
3032
namespace libfreenect2
3133
{
3234

examples/protonect/include/libfreenect2/frame_listener_impl.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,34 +28,34 @@
2828
#define FRAME_LISTENER_IMPL_H_
2929

3030
#include <map>
31-
#include <libfreenect2/threading.h>
3231
#include <libfreenect2/frame_listener.hpp>
3332

3433
namespace libfreenect2
3534
{
3635

3736
typedef std::map<Frame::Type, Frame*> FrameMap;
3837

39-
// TODO: reimplement, this is just some adhoc construct, probably performance can be improved
38+
class SyncMultiFrameListenerImpl;
39+
4040
class SyncMultiFrameListener : public FrameListener
4141
{
4242
public:
4343
SyncMultiFrameListener(unsigned int frame_types);
4444
virtual ~SyncMultiFrameListener();
4545

46+
bool hasNewFrame() const;
47+
48+
#ifdef LIBFREENECT2_THREADING_STDLIB
49+
bool waitForNewFrame(FrameMap &frame, int milliseconds);
50+
#endif // LIBFREENECT2_THREADING_STDLIB
4651
// for now the caller is responsible to release the frames when he is done
4752
void waitForNewFrame(FrameMap &frame);
4853

4954
void release(FrameMap &frame);
5055

5156
virtual bool onNewFrame(Frame::Type type, Frame *frame);
5257
private:
53-
libfreenect2::mutex mutex_;
54-
libfreenect2::condition_variable condition_;
55-
FrameMap next_frame_;
56-
57-
const unsigned int subscribed_frame_types_;
58-
unsigned int ready_frame_types_;
58+
SyncMultiFrameListenerImpl *impl_;
5959
};
6060

6161
} /* namespace libfreenect2 */

examples/protonect/src/frame_listener_impl.cpp

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,34 +25,86 @@
2525
*/
2626

2727
#include <libfreenect2/frame_listener_impl.h>
28+
#include <libfreenect2/threading.h>
2829

2930
namespace libfreenect2
3031
{
3132

3233
FrameListener::~FrameListener() {}
3334

34-
SyncMultiFrameListener::SyncMultiFrameListener(unsigned int frame_types) :
35+
class SyncMultiFrameListenerImpl
36+
{
37+
public:
38+
libfreenect2::mutex mutex_;
39+
libfreenect2::condition_variable condition_;
40+
FrameMap next_frame_;
41+
42+
const unsigned int subscribed_frame_types_;
43+
unsigned int ready_frame_types_;
44+
45+
SyncMultiFrameListenerImpl(unsigned int frame_types) :
3546
subscribed_frame_types_(frame_types),
3647
ready_frame_types_(0)
48+
{
49+
}
50+
51+
bool hasNewFrame() const
52+
{
53+
return ready_frame_types_ == subscribed_frame_types_;
54+
}
55+
};
56+
57+
SyncMultiFrameListener::SyncMultiFrameListener(unsigned int frame_types) :
58+
impl_(new SyncMultiFrameListenerImpl(frame_types))
3759
{
3860
}
3961

4062
SyncMultiFrameListener::~SyncMultiFrameListener()
4163
{
64+
delete impl_;
65+
}
66+
67+
bool SyncMultiFrameListener::hasNewFrame() const
68+
{
69+
libfreenect2::unique_lock l(impl_->mutex_);
70+
71+
return impl_->hasNewFrame();
72+
}
73+
74+
#ifdef LIBFREENECT2_THREADING_STDLIB
75+
bool SyncMultiFrameListener::waitForNewFrame(FrameMap &frame, int milliseconds)
76+
{
77+
libfreenect2::unique_lock l(impl_->mutex_);
78+
79+
auto predicate = std::bind(&SyncMultiFrameListenerImpl::hasNewFrame, impl_);
80+
81+
if(impl_->condition_.wait_for(l, std::chrono::milliseconds(milliseconds), predicate))
82+
{
83+
frame = impl_->next_frame_;
84+
impl_->next_frame_.clear();
85+
impl_->ready_frame_types_ = 0;
86+
87+
return true;
88+
}
89+
else
90+
{
91+
return false;
92+
}
4293
}
94+
#endif // LIBFREENECT2_THREADING_STDLIB
4395

4496
void SyncMultiFrameListener::waitForNewFrame(FrameMap &frame)
4597
{
46-
libfreenect2::unique_lock l(mutex_);
98+
libfreenect2::unique_lock l(impl_->mutex_);
4799

48-
while(ready_frame_types_ != subscribed_frame_types_)
100+
while(!impl_->hasNewFrame())
49101
{
50-
WAIT_CONDITION(condition_, mutex_, l)
102+
WAIT_CONDITION(impl_->condition_, impl_->mutex_, l)
51103
}
52104

53-
frame = next_frame_;
54-
next_frame_.clear();
55-
ready_frame_types_ = 0;
105+
frame = impl_->next_frame_;
106+
impl_->next_frame_.clear();
107+
impl_->ready_frame_types_ = 0;
56108
}
57109

58110
void SyncMultiFrameListener::release(FrameMap &frame)
@@ -68,28 +120,28 @@ void SyncMultiFrameListener::release(FrameMap &frame)
68120

69121
bool SyncMultiFrameListener::onNewFrame(Frame::Type type, Frame *frame)
70122
{
71-
if((subscribed_frame_types_ & type) == 0) return false;
123+
if((impl_->subscribed_frame_types_ & type) == 0) return false;
72124

73125
{
74-
libfreenect2::lock_guard l(mutex_);
126+
libfreenect2::lock_guard l(impl_->mutex_);
75127

76-
FrameMap::iterator it = next_frame_.find(type);
128+
FrameMap::iterator it = impl_->next_frame_.find(type);
77129

78-
if(it != next_frame_.end())
130+
if(it != impl_->next_frame_.end())
79131
{
80132
// replace frame
81133
delete it->second;
82134
it->second = frame;
83135
}
84136
else
85137
{
86-
next_frame_[type] = frame;
138+
impl_->next_frame_[type] = frame;
87139
}
88140

89-
ready_frame_types_ |= type;
141+
impl_->ready_frame_types_ |= type;
90142
}
91143

92-
condition_.notify_one();
144+
impl_->condition_.notify_one();
93145

94146
return true;
95147
}

0 commit comments

Comments
 (0)