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
|
manager.cpp
|
||||||
menu.cpp
|
menu.cpp
|
||||||
message.cpp
|
message.cpp
|
||||||
|
message_loop.cpp
|
||||||
paint_event.cpp
|
paint_event.cpp
|
||||||
popup_window.cpp
|
popup_window.cpp
|
||||||
preferred_size_event.cpp
|
preferred_size_event.cpp
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "ui/manager.h"
|
#include "ui/manager.h"
|
||||||
#include "ui/menu.h"
|
#include "ui/menu.h"
|
||||||
#include "ui/message.h"
|
#include "ui/message.h"
|
||||||
|
#include "ui/message_loop.h"
|
||||||
#include "ui/paint_event.h"
|
#include "ui/paint_event.h"
|
||||||
#include "ui/popup_window.h"
|
#include "ui/popup_window.h"
|
||||||
#include "ui/preferred_size_event.h"
|
#include "ui/preferred_size_event.h"
|
||||||
|
@ -11,8 +11,6 @@
|
|||||||
|
|
||||||
#include "ui/manager.h"
|
#include "ui/manager.h"
|
||||||
|
|
||||||
#include "base/chrono.h"
|
|
||||||
#include "base/thread.h"
|
|
||||||
#include "ui/gui.h"
|
#include "ui/gui.h"
|
||||||
#include "ui/intern.h"
|
#include "ui/intern.h"
|
||||||
|
|
||||||
@ -186,27 +184,10 @@ Manager::~Manager()
|
|||||||
|
|
||||||
void Manager::run()
|
void Manager::run()
|
||||||
{
|
{
|
||||||
base::Chrono chrono;
|
MessageLoop loop(this);
|
||||||
|
|
||||||
while (!jlist_empty(this->children)) {
|
while (!jlist_empty(this->children))
|
||||||
chrono.reset();
|
loop.pumpMessages();
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::generateMessages()
|
bool Manager::generateMessages()
|
||||||
@ -1196,6 +1177,9 @@ void Manager::invalidateDisplayRegion(const JRegion region)
|
|||||||
|
|
||||||
void Manager::collectGarbage()
|
void Manager::collectGarbage()
|
||||||
{
|
{
|
||||||
|
if (m_garbage.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
for (WidgetsList::iterator
|
for (WidgetsList::iterator
|
||||||
it = m_garbage.begin(),
|
it = m_garbage.begin(),
|
||||||
end = m_garbage.end(); it != end; ++it) {
|
end = m_garbage.end(); it != end; ++it) {
|
||||||
|
@ -28,12 +28,11 @@ namespace ui {
|
|||||||
// Returns true if there are messages in the queue to be
|
// Returns true if there are messages in the queue to be
|
||||||
// distpatched through jmanager_dispatch_messages().
|
// distpatched through jmanager_dispatch_messages().
|
||||||
bool generateMessages();
|
bool generateMessages();
|
||||||
|
|
||||||
void dispatchMessages();
|
void dispatchMessages();
|
||||||
|
void enqueueMessage(Message* msg);
|
||||||
|
|
||||||
void addToGarbage(Widget* widget);
|
void addToGarbage(Widget* widget);
|
||||||
|
void collectGarbage();
|
||||||
void enqueueMessage(Message* msg);
|
|
||||||
|
|
||||||
Window* getTopWindow();
|
Window* getTopWindow();
|
||||||
Window* getForegroundWindow();
|
Window* getForegroundWindow();
|
||||||
@ -72,7 +71,6 @@ namespace ui {
|
|||||||
private:
|
private:
|
||||||
void layoutManager(JRect rect);
|
void layoutManager(JRect rect);
|
||||||
void pumpQueue();
|
void pumpQueue();
|
||||||
void collectGarbage();
|
|
||||||
void generateSetCursorMessage();
|
void generateSetCursorMessage();
|
||||||
static void removeWidgetFromDests(Widget* widget, Message* msg);
|
static void removeWidgetFromDests(Widget* widget, Message* msg);
|
||||||
static bool someParentIsFocusStop(Widget* widget);
|
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();
|
openWindow();
|
||||||
|
|
||||||
Manager* manager = getManager();
|
MessageLoop loop(getManager());
|
||||||
|
|
||||||
m_is_foreground = true;
|
m_is_foreground = true;
|
||||||
|
|
||||||
while (!(this->flags & JI_HIDDEN)) {
|
while (!(this->flags & JI_HIDDEN))
|
||||||
if (manager->generateMessages())
|
loop.pumpMessages();
|
||||||
manager->dispatchMessages();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_is_foreground = false;
|
m_is_foreground = false;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user