add fps modifier for animation
This commit is contained in:
parent
274155b1da
commit
4385ac623d
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* An Animation Implementation
|
* An Animation Implementation
|
||||||
* Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
|
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
|
||||||
*
|
*
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@ -27,15 +28,13 @@ namespace nana
|
|||||||
friend class animation;
|
friend class animation;
|
||||||
public:
|
public:
|
||||||
/// function which builds frames.
|
/// function which builds frames.
|
||||||
typedef std::function<bool(std::size_t pos, paint::graphics&, nana::size&)> framebuilder;
|
using framebuilder = std::function<bool(std::size_t pos, paint::graphics&, nana::size&)>;
|
||||||
|
|
||||||
struct impl;
|
struct impl;
|
||||||
public:
|
public:
|
||||||
frameset();
|
frameset();
|
||||||
void push_back(const paint::image&); ///< Inserts frames at the end.
|
void push_back(paint::image); ///< Inserts frames at the end.
|
||||||
void push_back(paint::image&&);
|
void push_back(framebuilder fb, std::size_t length); ///< Insters a framebuilder and the number of frames that it generates.
|
||||||
void push_back(framebuilder& fb, std::size_t length); ///< Insters a framebuilder and the number of frames that it generates.
|
|
||||||
void push_back(framebuilder&& fb, std::size_t length); ///< Insters a framebuilder and the number of frames that it generates.
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<impl> impl_;
|
std::shared_ptr<impl> impl_;
|
||||||
};
|
};
|
||||||
@ -51,9 +50,9 @@ namespace nana
|
|||||||
struct impl;
|
struct impl;
|
||||||
class performance_manager;
|
class performance_manager;
|
||||||
public:
|
public:
|
||||||
animation();
|
animation(std::size_t fps = 23);
|
||||||
|
|
||||||
void push_back(const frameset& frms);
|
void push_back(frameset frms);
|
||||||
/*
|
/*
|
||||||
void branch(const std::string& name, const frameset& frms)
|
void branch(const std::string& name, const frameset& frms)
|
||||||
{
|
{
|
||||||
@ -75,6 +74,9 @@ namespace nana
|
|||||||
void pause();
|
void pause();
|
||||||
|
|
||||||
void output(window wd, const nana::point& pos);
|
void output(window wd, const nana::point& pos);
|
||||||
|
|
||||||
|
void fps(std::size_t n);
|
||||||
|
std::size_t fps() const;
|
||||||
private:
|
private:
|
||||||
impl * impl_;
|
impl * impl_;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -44,7 +44,6 @@ namespace nana
|
|||||||
widget * widget_{nullptr};
|
widget * widget_{nullptr};
|
||||||
nana::paint::graphics* graph_{nullptr};
|
nana::paint::graphics* graph_{nullptr};
|
||||||
unsigned draw_width_{static_cast<unsigned>(-1)};
|
unsigned draw_width_{static_cast<unsigned>(-1)};
|
||||||
//bool has_value_{true}; //deprecated
|
|
||||||
bool unknown_{false};
|
bool unknown_{false};
|
||||||
unsigned max_{100};
|
unsigned max_{100};
|
||||||
unsigned value_{0};
|
unsigned value_{0};
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* An Animation Implementation
|
* An Animation Implementation
|
||||||
* Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
|
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
|
||||||
*
|
*
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@ -48,11 +49,7 @@ namespace nana
|
|||||||
std::size_t length;
|
std::size_t length;
|
||||||
std::function<bool(std::size_t, paint::graphics&, nana::size&)> frbuilder;
|
std::function<bool(std::size_t, paint::graphics&, nana::size&)> frbuilder;
|
||||||
|
|
||||||
framebuilder(const std::function<bool(std::size_t, paint::graphics&, nana::size&)>& f, std::size_t l)
|
framebuilder(std::function<bool(std::size_t, paint::graphics&, nana::size&)> f, std::size_t l)
|
||||||
: length(l), frbuilder(f)
|
|
||||||
{}
|
|
||||||
|
|
||||||
framebuilder(std::size_t l, std::function<bool(std::size_t, paint::graphics&, nana::size)>&& f)
|
|
||||||
: length(l), frbuilder(std::move(f))
|
: length(l), frbuilder(std::move(f))
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
@ -65,28 +62,16 @@ namespace nana
|
|||||||
framebuilder
|
framebuilder
|
||||||
};
|
};
|
||||||
|
|
||||||
frame(const paint::image& r)
|
frame(paint::image img)
|
||||||
: type(kind::oneshot)
|
: type(kind::oneshot)
|
||||||
{
|
{
|
||||||
u.oneshot = new paint::image(r);
|
u.oneshot = new paint::image(std::move(img));
|
||||||
}
|
}
|
||||||
|
|
||||||
frame(paint::image&& r)
|
frame(std::function<bool(std::size_t, paint::graphics&, nana::size&)> frbuilder, std::size_t length)
|
||||||
: type(kind::oneshot)
|
|
||||||
{
|
|
||||||
u.oneshot = new paint::image(std::move(r));
|
|
||||||
}
|
|
||||||
|
|
||||||
frame(const std::function<bool(std::size_t, paint::graphics&, nana::size&)>& frbuilder, std::size_t length)
|
|
||||||
: type(kind::framebuilder)
|
: type(kind::framebuilder)
|
||||||
{
|
{
|
||||||
u.frbuilder = new framebuilder(frbuilder, length);
|
u.frbuilder = new framebuilder(std::move(frbuilder), length);
|
||||||
}
|
|
||||||
|
|
||||||
frame(std::function<bool(std::size_t, paint::graphics&, nana::size&)>&& frbuilder, std::size_t length)
|
|
||||||
: type(kind::framebuilder)
|
|
||||||
{
|
|
||||||
u.frbuilder = new framebuilder(frbuilder, length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
frame(const frame& r)
|
frame(const frame& r)
|
||||||
@ -323,29 +308,15 @@ namespace nana
|
|||||||
: impl_(new impl)
|
: impl_(new impl)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void frameset::push_back(const paint::image& m)
|
void frameset::push_back(paint::image img)
|
||||||
{
|
{
|
||||||
bool located = impl_->this_frame != impl_->frames.end();
|
bool located = impl_->this_frame != impl_->frames.end();
|
||||||
impl_->frames.emplace_back(m);
|
impl_->frames.emplace_back(std::move(img));
|
||||||
if(false == located)
|
if(false == located)
|
||||||
impl_->this_frame = impl_->frames.begin();
|
impl_->this_frame = impl_->frames.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void frameset::push_back(paint::image&& m)
|
void frameset::push_back(framebuilder fb, std::size_t length)
|
||||||
{
|
|
||||||
impl_->frames.emplace_back(std::move(m));
|
|
||||||
if(1 == impl_->frames.size())
|
|
||||||
impl_->this_frame = impl_->frames.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
void frameset::push_back(framebuilder&fb, std::size_t length)
|
|
||||||
{
|
|
||||||
impl_->frames.emplace_back(fb, length);
|
|
||||||
if(1 == impl_->frames.size())
|
|
||||||
impl_->this_frame = impl_->frames.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
void frameset::push_back(framebuilder&& fb, std::size_t length)
|
|
||||||
{
|
{
|
||||||
impl_->frames.emplace_back(std::move(fb), length);
|
impl_->frames.emplace_back(std::move(fb), length);
|
||||||
if(1 == impl_->frames.size())
|
if(1 == impl_->frames.size())
|
||||||
@ -365,10 +336,14 @@ namespace nana
|
|||||||
|
|
||||||
std::size_t active; //The number of active animations
|
std::size_t active; //The number of active animations
|
||||||
std::shared_ptr<std::thread> thread;
|
std::shared_ptr<std::thread> thread;
|
||||||
|
|
||||||
|
std::size_t fps;
|
||||||
|
double interval; //milliseconds between 2 frames.
|
||||||
double performance_parameter;
|
double performance_parameter;
|
||||||
};
|
};
|
||||||
|
|
||||||
thread_variable * insert(impl* p);
|
void insert(impl* p);
|
||||||
|
void set_fps(impl*, std::size_t new_fps);
|
||||||
void close(impl* p);
|
void close(impl* p);
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
private:
|
private:
|
||||||
@ -380,8 +355,9 @@ namespace nana
|
|||||||
|
|
||||||
struct animation::impl
|
struct animation::impl
|
||||||
{
|
{
|
||||||
bool looped;
|
bool looped{false};
|
||||||
volatile bool paused;
|
volatile bool paused{true};
|
||||||
|
std::size_t fps;
|
||||||
|
|
||||||
std::list<frameset> framesets;
|
std::list<frameset> framesets;
|
||||||
std::map<std::string, branch_t> branches;
|
std::map<std::string, branch_t> branches;
|
||||||
@ -399,17 +375,21 @@ namespace nana
|
|||||||
static performance_manager * perf_manager;
|
static performance_manager * perf_manager;
|
||||||
|
|
||||||
|
|
||||||
impl()
|
impl(std::size_t fps)
|
||||||
: looped(false), paused(true)
|
: fps(fps)
|
||||||
{
|
{
|
||||||
state.this_frameset = framesets.begin();
|
state.this_frameset = framesets.begin();
|
||||||
|
|
||||||
|
if (!perf_manager)
|
||||||
{
|
{
|
||||||
nana::internal_scope_guard lock;
|
nana::internal_scope_guard lock;
|
||||||
if(nullptr == perf_manager)
|
if (!perf_manager)
|
||||||
perf_manager = new performance_manager;
|
{
|
||||||
|
auto pm = new performance_manager;
|
||||||
|
perf_manager = pm;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
thr_variable = perf_manager->insert(this);
|
perf_manager->insert(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
~impl()
|
~impl()
|
||||||
@ -457,46 +437,78 @@ namespace nana
|
|||||||
};//end struct animation::impl
|
};//end struct animation::impl
|
||||||
|
|
||||||
//class animation::performance_manager
|
//class animation::performance_manager
|
||||||
auto animation::performance_manager::insert(impl* p) -> thread_variable *
|
void animation::performance_manager::insert(impl* p)
|
||||||
{
|
{
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||||
for(auto thr : threads_)
|
for(auto thr : threads_)
|
||||||
{
|
{
|
||||||
std::lock_guard<decltype(thr->mutex)> privlock(thr->mutex);
|
std::lock_guard<decltype(thr->mutex)> privlock(thr->mutex);
|
||||||
|
|
||||||
if(thr->performance_parameter / (thr->animations.size() + 1) <= 43.3)
|
if ((thr->fps == p->fps) && (thr->performance_parameter / (thr->animations.size() + 1) <= 43.3))
|
||||||
{
|
{
|
||||||
|
p->thr_variable = thr;
|
||||||
thr->animations.push_back(p);
|
thr->animations.push_back(p);
|
||||||
return thr;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto thr = new thread_variable;
|
auto thr = new thread_variable;
|
||||||
thr->animations.push_back(p);
|
thr->animations.push_back(p);
|
||||||
thr->performance_parameter = 0.0;
|
thr->performance_parameter = 0.0;
|
||||||
|
thr->fps = p->fps;
|
||||||
|
thr->interval = 1000.0 / double(p->fps);
|
||||||
thr->thread = std::make_shared<std::thread>([this, thr]()
|
thr->thread = std::make_shared<std::thread>([this, thr]()
|
||||||
{
|
{
|
||||||
_m_perf_thread(thr);
|
_m_perf_thread(thr);
|
||||||
});
|
});
|
||||||
|
|
||||||
threads_.push_back(thr);
|
threads_.push_back(thr);
|
||||||
return thr;
|
p->thr_variable = thr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void animation::performance_manager::set_fps(impl* p, std::size_t new_fps)
|
||||||
|
{
|
||||||
|
if (p->fps == new_fps)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||||
|
auto i = std::find(threads_.begin(), threads_.end(), p->thr_variable);
|
||||||
|
if (i == threads_.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
p->fps = new_fps;
|
||||||
|
auto thr = *i;
|
||||||
|
|
||||||
|
//Simply modify the fps parameter if the thread just has one animation.
|
||||||
|
if (thr->animations.size() == 1)
|
||||||
|
{
|
||||||
|
thr->fps = new_fps;
|
||||||
|
thr->interval = 1000.0 / double(new_fps);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<decltype(thr->mutex)> privlock(thr->mutex);
|
||||||
|
auto u = std::find(thr->animations.begin(), thr->animations.end(), p);
|
||||||
|
if (u != thr->animations.end())
|
||||||
|
thr->animations.erase(u);
|
||||||
|
|
||||||
|
p->thr_variable = nullptr;
|
||||||
|
insert(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void animation::performance_manager::close(impl* p)
|
void animation::performance_manager::close(impl* p)
|
||||||
{
|
{
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||||
for(auto thr : threads_)
|
auto i = std::find(threads_.begin(), threads_.end(), p->thr_variable);
|
||||||
{
|
if (i == threads_.end())
|
||||||
std::lock_guard<decltype(thr->mutex)> privlock(thr->mutex);
|
return;
|
||||||
|
|
||||||
auto i = std::find(thr->animations.begin(), thr->animations.end(), p);
|
auto thr = *i;
|
||||||
if(i != thr->animations.end())
|
std::lock_guard<decltype(thr->mutex)> privlock(thr->mutex);
|
||||||
{
|
|
||||||
thr->animations.erase(i);
|
auto u = std::find(thr->animations.begin(), thr->animations.end(), p);
|
||||||
return;
|
if(u != thr->animations.end())
|
||||||
}
|
thr->animations.erase(u);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool animation::performance_manager::empty() const
|
bool animation::performance_manager::empty() const
|
||||||
@ -542,8 +554,8 @@ namespace nana
|
|||||||
if(thrvar->active)
|
if(thrvar->active)
|
||||||
{
|
{
|
||||||
thrvar->performance_parameter = tmpiece.calc();
|
thrvar->performance_parameter = tmpiece.calc();
|
||||||
if(thrvar->performance_parameter < 43.4)
|
if(thrvar->performance_parameter < thrvar->interval)
|
||||||
nana::system::sleep(static_cast<unsigned>(43.4 - thrvar->performance_parameter));
|
nana::system::sleep(static_cast<unsigned>(thrvar->interval - thrvar->performance_parameter));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -557,15 +569,15 @@ namespace nana
|
|||||||
}
|
}
|
||||||
//end class animation::performance_manager
|
//end class animation::performance_manager
|
||||||
|
|
||||||
animation::animation()
|
animation::animation(std::size_t fps)
|
||||||
: impl_(new impl)
|
: impl_(new impl(fps))
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void animation::push_back(const frameset& frms)
|
void animation::push_back(frameset frms)
|
||||||
{
|
{
|
||||||
impl_->framesets.emplace_back(frms);
|
impl_->framesets.emplace_back(std::move(frms));
|
||||||
if(1 == impl_->framesets.size())
|
if(1 == impl_->framesets.size())
|
||||||
impl_->state.this_frameset = impl_->framesets.begin();
|
impl_->state.this_frameset = impl_->framesets.begin();
|
||||||
}
|
}
|
||||||
@ -634,6 +646,19 @@ namespace nana
|
|||||||
}
|
}
|
||||||
output.points.push_back(pos);
|
output.points.push_back(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void animation::fps(std::size_t n)
|
||||||
|
{
|
||||||
|
if (n == impl_->fps)
|
||||||
|
return;
|
||||||
|
|
||||||
|
impl::perf_manager->set_fps(impl_, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t animation::fps() const
|
||||||
|
{
|
||||||
|
return impl_->fps;
|
||||||
|
}
|
||||||
//end class animation
|
//end class animation
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -108,7 +108,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
rectangle r = graph.size();
|
rectangle r = graph.size();
|
||||||
graph.gradual_rectangle(r, colors::button_face_shadow_end, colors::button_face_shadow_start, true);
|
graph.gradual_rectangle(r, colors::button_face_shadow_end, colors::button_face_shadow_start, true);
|
||||||
::nana::color lt{ 0x80, 0x80, 0x80 }, rb{colors::white};
|
::nana::color lt{ colors::gray }, rb{colors::white};
|
||||||
graph.frame_rectangle(r, lt, lt, rb, rb);
|
graph.frame_rectangle(r, lt, lt, rb, rb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user