mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-01 01:20:25 +00:00
Add MessageLoop to avoid 100% CPU in foreground windows.
This commit is contained in:
parent
5529c62c9f
commit
8e7b16c3b1
@ -27,6 +27,7 @@ add_library(ui-lib
|
||||
manager.cpp
|
||||
menu.cpp
|
||||
message.cpp
|
||||
message_loop.cpp
|
||||
paint_event.cpp
|
||||
popup_window.cpp
|
||||
preferred_size_event.cpp
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "ui/manager.h"
|
||||
#include "ui/menu.h"
|
||||
#include "ui/message.h"
|
||||
#include "ui/message_loop.h"
|
||||
#include "ui/paint_event.h"
|
||||
#include "ui/popup_window.h"
|
||||
#include "ui/preferred_size_event.h"
|
||||
|
@ -11,8 +11,6 @@
|
||||
|
||||
#include "ui/manager.h"
|
||||
|
||||
#include "base/chrono.h"
|
||||
#include "base/thread.h"
|
||||
#include "ui/gui.h"
|
||||
#include "ui/intern.h"
|
||||
|
||||
@ -186,27 +184,10 @@ Manager::~Manager()
|
||||
|
||||
void Manager::run()
|
||||
{
|
||||
base::Chrono chrono;
|
||||
MessageLoop loop(this);
|
||||
|
||||
while (!jlist_empty(this->children)) {
|
||||
chrono.reset();
|
||||
|
||||
if (generateMessages()) {
|
||||
dispatchMessages();
|
||||
}
|
||||
else if (!m_garbage.empty()) {
|
||||
collectGarbage();
|
||||
}
|
||||
|
||||
// If the dispatching of messages was faster than 10 milliseconds,
|
||||
// it means that the process is not using a lot of CPU, so we can
|
||||
// wait the difference to cover those 10 milliseconds
|
||||
// sleeping. With this code we can avoid 100% CPU usage (a
|
||||
// property of Allegro 4 polling nature).
|
||||
double elapsedMSecs = chrono.elapsed() * 1000.0;
|
||||
if (elapsedMSecs > 0.0 && elapsedMSecs < 10.0)
|
||||
base::this_thread::sleep_for((10.0 - elapsedMSecs) / 1000.0);
|
||||
}
|
||||
while (!jlist_empty(this->children))
|
||||
loop.pumpMessages();
|
||||
}
|
||||
|
||||
bool Manager::generateMessages()
|
||||
@ -1196,6 +1177,9 @@ void Manager::invalidateDisplayRegion(const JRegion region)
|
||||
|
||||
void Manager::collectGarbage()
|
||||
{
|
||||
if (m_garbage.empty())
|
||||
return;
|
||||
|
||||
for (WidgetsList::iterator
|
||||
it = m_garbage.begin(),
|
||||
end = m_garbage.end(); it != end; ++it) {
|
||||
|
@ -28,12 +28,11 @@ namespace ui {
|
||||
// Returns true if there are messages in the queue to be
|
||||
// distpatched through jmanager_dispatch_messages().
|
||||
bool generateMessages();
|
||||
|
||||
void dispatchMessages();
|
||||
void enqueueMessage(Message* msg);
|
||||
|
||||
void addToGarbage(Widget* widget);
|
||||
|
||||
void enqueueMessage(Message* msg);
|
||||
void collectGarbage();
|
||||
|
||||
Window* getTopWindow();
|
||||
Window* getForegroundWindow();
|
||||
@ -72,7 +71,6 @@ namespace ui {
|
||||
private:
|
||||
void layoutManager(JRect rect);
|
||||
void pumpQueue();
|
||||
void collectGarbage();
|
||||
void generateSetCursorMessage();
|
||||
static void removeWidgetFromDests(Widget* widget, Message* msg);
|
||||
static bool someParentIsFocusStop(Widget* widget);
|
||||
|
43
src/ui/message_loop.cpp
Normal file
43
src/ui/message_loop.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
// ASEPRITE gui library
|
||||
// Copyright (C) 2001-2012 David Capello
|
||||
//
|
||||
// This source file is ditributed under a BSD-like license, please
|
||||
// read LICENSE.txt for more information.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "ui/message_loop.h"
|
||||
|
||||
#include "base/chrono.h"
|
||||
#include "base/thread.h"
|
||||
#include "ui/manager.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
MessageLoop::MessageLoop(Manager* manager)
|
||||
: m_manager(manager)
|
||||
{
|
||||
}
|
||||
|
||||
void MessageLoop::pumpMessages()
|
||||
{
|
||||
base::Chrono chrono;
|
||||
|
||||
if (m_manager->generateMessages()) {
|
||||
m_manager->dispatchMessages();
|
||||
}
|
||||
else {
|
||||
m_manager->collectGarbage();
|
||||
}
|
||||
|
||||
// If the dispatching of messages was faster than 10 milliseconds,
|
||||
// it means that the process is not using a lot of CPU, so we can
|
||||
// wait the difference to cover those 10 milliseconds
|
||||
// sleeping. With this code we can avoid 100% CPU usage (a
|
||||
// property of Allegro 4 polling nature).
|
||||
double elapsedMSecs = chrono.elapsed() * 1000.0;
|
||||
if (elapsedMSecs > 0.0 && elapsedMSecs < 10.0)
|
||||
base::this_thread::sleep_for((10.0 - elapsedMSecs) / 1000.0);
|
||||
}
|
||||
|
||||
} // namespace ui
|
27
src/ui/message_loop.h
Normal file
27
src/ui/message_loop.h
Normal file
@ -0,0 +1,27 @@
|
||||
// ASEPRITE gui library
|
||||
// Copyright (C) 2001-2012 David Capello
|
||||
//
|
||||
// This source file is ditributed under a BSD-like license, please
|
||||
// read LICENSE.txt for more information.
|
||||
|
||||
#ifndef UI_MESSAGE_LOOP_H_INCLUDED
|
||||
#define UI_MESSAGE_LOOP_H_INCLUDED
|
||||
|
||||
namespace ui {
|
||||
|
||||
class Manager;
|
||||
|
||||
class MessageLoop
|
||||
{
|
||||
public:
|
||||
MessageLoop(Manager* manager);
|
||||
|
||||
void pumpMessages();
|
||||
|
||||
private:
|
||||
Manager* m_manager;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif
|
@ -233,14 +233,12 @@ void Window::openWindowInForeground()
|
||||
{
|
||||
openWindow();
|
||||
|
||||
Manager* manager = getManager();
|
||||
MessageLoop loop(getManager());
|
||||
|
||||
m_is_foreground = true;
|
||||
|
||||
while (!(this->flags & JI_HIDDEN)) {
|
||||
if (manager->generateMessages())
|
||||
manager->dispatchMessages();
|
||||
}
|
||||
while (!(this->flags & JI_HIDDEN))
|
||||
loop.pumpMessages();
|
||||
|
||||
m_is_foreground = false;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user