[webkit-changes] cvs commit: WebCore/kwq KWQKHTMLPart.h
KWQKHTMLPart.mm KWQObject.h KWQObject.mm KWQPageState.h
KWQPageState.mm KWQTimer.h KWQTimer.mm WebCoreBridge.mm
Darin
darin at opensource.apple.com
Mon Nov 7 12:52:14 PST 2005
darin 05/11/07 12:52:14
Modified: . ChangeLog
khtml/ecma kjs_window.cpp kjs_window.h
kwq KWQKHTMLPart.h KWQKHTMLPart.mm KWQObject.h
KWQObject.mm KWQPageState.h KWQPageState.mm
KWQTimer.h KWQTimer.mm WebCoreBridge.mm
Log:
Reviewed by Tim Omernick.
- speed up timers by using CFTimerRunLoopRef instead of NSTimer
* kwq/KWQObject.h: Removed pauseTimer, resumeTimers, and _addTimer, added timerIntervals and
restartTimer. Made KWQObjectSenderScope functions be inline.
* kwq/KWQObject.mm:
(timerFired): Added. Function called when the CFRunLoopTimerRef fires. Puts the timer into the
deferred timer array if timers are deferred, otherwise makes a QTimerEvent and calls timerEvent
on the target.
(QObject::startTimer): Moved most of the code inside restartTimer. This now just picks a new
timer ID and calls restartTimer.
(QObject::restartTimer): Added. Creates a KWQObjectTimer and puts it in a timers dictionary.
That includes creating a CFRunLoopTimer and scheduling it on the current run loop.
(QObject::timerIntervals): Added. Looks up a timer and returns the intervals for next time to
fire and the "fire again" interval.
(deleteTimer): Added. Invalidates and then removes a timer.
(QObject::killTimer): Changed to use deleteTimer to do most of its work.
(deleteOneTimer): Added. Calls deleteTimer.
(QObject::killTimers): Changed to use deleteOneTimer to do most of its work.
(sendDeferredTimerEvent): Added. Creates a QTimerEvent and calls timerEvent on the target.
(sendDeferredTimerEvents): Added. Calls sendDeferredTimerEvent in a loop on all the deferred timers.
(QObject::setDefersTimers): Updated to call sendDeferredTimerEvents as needed.
* kwq/KWQTimer.h:
(QTimer::QTimer): Made constructor inline and removed the optional parameter.
(QTimer::isActive): Made inline.
(QTimer::fireDate): Added. Inline function.
Got rid of the NSTimer and added a CFRunLoopTimer.
* kwq/KWQTimer.mm:
(timerFired): Added. Calls fire on the QTimer object.
(QTimer::start): Changed to create a CFRunLoopTimer.
(QTimer::stop): Changed to use CFRunLoopTimer functions.
(QTimer::fire): Ditto.
(deleteKWQSlot): Added. Used as delete function for the CFRunLoopTimerContext below.
(singleShotTimerFired): Added. Used as the fire function for the CFRunLoopTimerContext below.
(QTimer::singleShot): Changed to create, schedule, and release a CFRunLoopTimer.
* khtml/ecma/kjs_window.h: Added PausedTimeouts class. Moved WindowQObject class up in the
file so it can be used inline in the implementation of the Window class, and changed to
use the PausedTimeouts class intead of a QMap to store the paused timeouts.
* khtml/ecma/kjs_window.cpp:
(KJS::ScheduledAction::execute): Put a check for nil part at the start; this replaces
a check in the caller and a check partway down this function (after the part was
already dereferenced). Fixed message handling so the message is not converted to ascii
and back. Added an isObject() check so we won't crash if the passed function is a value
that's not an object. Changed check for function vs. script to check for a function
of nil instead of using a separate boolean.
(KJS::WindowQObject::pauseTimeouts): Updated to create the new PausedTimeouts object,
using the new QObject::timerIntervals function rather than the old QObject::pauseTimer
function. This means that the paused timers are entirely stored in the PausedTimeouts
object instead of being half in a QMap and the other half inside the QObject itself.
(KJS::WindowQObject::resumeTimeouts): Ditto, using the new QObject::restartTimer function.
(KJS::PausedTimeouts::~PausedTimeouts): Added. Deletes the stored timeouts, including
the scheduled actions, unless the timeouts have already been resumed (in which case the
m_array field will be 0).
* kwq/KWQKHTMLPart.h: Renamed pause/resumeActions to pause/resumeTimeouts and made them
use the PausedTimeouts class and no longer take a key parameter.
* kwq/KWQKHTMLPart.mm:
(KWQKHTMLPart::redirectionTimerStartedOrStopped): Use the new fireDate() function rathe than
the old getNSTimer() function to get the fire date.
(KWQKHTMLPart::pauseTimeouts): Remove the call to hasTimeouts and the key parameter.
(KWQKHTMLPart::resumeTimeouts): Remove the key parameter.
(KWQKHTMLPart::openURLFromPageCache): Change the timeout handling to use PausedTimeouts instead
of a QMap for the paused timeouts.
* kwq/KWQPageState.h: Changed to use PausedTimeouts instead of a QMap for timeouts.
Added a pausedTimeouts parameter to the initializer and removed the setPausedActions: method.
* kwq/KWQPageState.mm:
(-[KWQPageState initWithDocument:URL:windowProperties:locationProperties:interpreterBuiltins:pausedTimeouts:]):
Added code where it sets the pausedTimouts.
(-[KWQPageState pausedTimeouts]): Added.
(-[KWQPageState clear]): Added code to delete the pausedTimeouts and to deref mousePressNode.
(-[KWQPageState invalidate]): Fixed bug where document would not be deref'd if the view was 0.
(-[KWQPageState dealloc]): Removed code to deref mousePressNode since that's now handled in the clear method.
(-[KWQPageState finalize]): Set document to 0 after deref for consistency.
* kwq/WebCoreBridge.mm: (-[WebCoreBridge saveDocumentToPageCache]): Changed to pass in the
paused timeouts using the new pauseTimeouts function.
Revision Changes Path
1.341 +83 -0 WebCore/ChangeLog
Index: ChangeLog
===================================================================
RCS file: /cvs/root/WebCore/ChangeLog,v
retrieving revision 1.340
retrieving revision 1.341
diff -u -r1.340 -r1.341
--- ChangeLog 7 Nov 2005 19:59:20 -0000 1.340
+++ ChangeLog 7 Nov 2005 20:52:05 -0000 1.341
@@ -1,3 +1,86 @@
+2005-11-07 Darin Adler <darin at apple.com>
+
+ Reviewed by Tim Omernick.
+
+ - speed up timers by using CFTimerRunLoopRef instead of NSTimer
+
+ * kwq/KWQObject.h: Removed pauseTimer, resumeTimers, and _addTimer, added timerIntervals and
+ restartTimer. Made KWQObjectSenderScope functions be inline.
+ * kwq/KWQObject.mm:
+ (timerFired): Added. Function called when the CFRunLoopTimerRef fires. Puts the timer into the
+ deferred timer array if timers are deferred, otherwise makes a QTimerEvent and calls timerEvent
+ on the target.
+ (QObject::startTimer): Moved most of the code inside restartTimer. This now just picks a new
+ timer ID and calls restartTimer.
+ (QObject::restartTimer): Added. Creates a KWQObjectTimer and puts it in a timers dictionary.
+ That includes creating a CFRunLoopTimer and scheduling it on the current run loop.
+ (QObject::timerIntervals): Added. Looks up a timer and returns the intervals for next time to
+ fire and the "fire again" interval.
+ (deleteTimer): Added. Invalidates and then removes a timer.
+ (QObject::killTimer): Changed to use deleteTimer to do most of its work.
+ (deleteOneTimer): Added. Calls deleteTimer.
+ (QObject::killTimers): Changed to use deleteOneTimer to do most of its work.
+ (sendDeferredTimerEvent): Added. Creates a QTimerEvent and calls timerEvent on the target.
+ (sendDeferredTimerEvents): Added. Calls sendDeferredTimerEvent in a loop on all the deferred timers.
+ (QObject::setDefersTimers): Updated to call sendDeferredTimerEvents as needed.
+
+ * kwq/KWQTimer.h:
+ (QTimer::QTimer): Made constructor inline and removed the optional parameter.
+ (QTimer::isActive): Made inline.
+ (QTimer::fireDate): Added. Inline function.
+ Got rid of the NSTimer and added a CFRunLoopTimer.
+ * kwq/KWQTimer.mm:
+ (timerFired): Added. Calls fire on the QTimer object.
+ (QTimer::start): Changed to create a CFRunLoopTimer.
+ (QTimer::stop): Changed to use CFRunLoopTimer functions.
+ (QTimer::fire): Ditto.
+ (deleteKWQSlot): Added. Used as delete function for the CFRunLoopTimerContext below.
+ (singleShotTimerFired): Added. Used as the fire function for the CFRunLoopTimerContext below.
+ (QTimer::singleShot): Changed to create, schedule, and release a CFRunLoopTimer.
+
+ * khtml/ecma/kjs_window.h: Added PausedTimeouts class. Moved WindowQObject class up in the
+ file so it can be used inline in the implementation of the Window class, and changed to
+ use the PausedTimeouts class intead of a QMap to store the paused timeouts.
+ * khtml/ecma/kjs_window.cpp:
+ (KJS::ScheduledAction::execute): Put a check for nil part at the start; this replaces
+ a check in the caller and a check partway down this function (after the part was
+ already dereferenced). Fixed message handling so the message is not converted to ascii
+ and back. Added an isObject() check so we won't crash if the passed function is a value
+ that's not an object. Changed check for function vs. script to check for a function
+ of nil instead of using a separate boolean.
+ (KJS::WindowQObject::pauseTimeouts): Updated to create the new PausedTimeouts object,
+ using the new QObject::timerIntervals function rather than the old QObject::pauseTimer
+ function. This means that the paused timers are entirely stored in the PausedTimeouts
+ object instead of being half in a QMap and the other half inside the QObject itself.
+ (KJS::WindowQObject::resumeTimeouts): Ditto, using the new QObject::restartTimer function.
+ (KJS::PausedTimeouts::~PausedTimeouts): Added. Deletes the stored timeouts, including
+ the scheduled actions, unless the timeouts have already been resumed (in which case the
+ m_array field will be 0).
+
+ * kwq/KWQKHTMLPart.h: Renamed pause/resumeActions to pause/resumeTimeouts and made them
+ use the PausedTimeouts class and no longer take a key parameter.
+ * kwq/KWQKHTMLPart.mm:
+ (KWQKHTMLPart::redirectionTimerStartedOrStopped): Use the new fireDate() function rathe than
+ the old getNSTimer() function to get the fire date.
+ (KWQKHTMLPart::pauseTimeouts): Remove the call to hasTimeouts and the key parameter.
+ (KWQKHTMLPart::resumeTimeouts): Remove the key parameter.
+ (KWQKHTMLPart::openURLFromPageCache): Change the timeout handling to use PausedTimeouts instead
+ of a QMap for the paused timeouts.
+
+ * kwq/KWQPageState.h: Changed to use PausedTimeouts instead of a QMap for timeouts.
+ Added a pausedTimeouts parameter to the initializer and removed the setPausedActions: method.
+ * kwq/KWQPageState.mm:
+ (-[KWQPageState initWithDocument:URL:windowProperties:locationProperties:interpreterBuiltins:pausedTimeouts:]):
+ Added code where it sets the pausedTimouts.
+ (-[KWQPageState pausedTimeouts]): Added.
+ (-[KWQPageState clear]): Added code to delete the pausedTimeouts and to deref mousePressNode.
+ (-[KWQPageState invalidate]): Fixed bug where document would not be deref'd if the view was 0.
+ (-[KWQPageState dealloc]): Removed code to deref mousePressNode since that's now handled in the clear method.
+ (-[KWQPageState finalize]): Set document to 0 after deref for consistency.
+
+ * kwq/WebCoreBridge.mm: (-[WebCoreBridge saveDocumentToPageCache]): Changed to pass in the
+ paused timeouts using the new pauseTimeouts function.
+
2005-11-07 Justin Garcia <justin.garcia at apple.com>
Reviewed by harrison
1.186 +109 -199 WebCore/khtml/ecma/kjs_window.cpp
Index: kjs_window.cpp
===================================================================
RCS file: /cvs/root/WebCore/khtml/ecma/kjs_window.cpp,v
retrieving revision 1.185
retrieving revision 1.186
diff -u -r1.185 -r1.186
--- kjs_window.cpp 28 Oct 2005 00:49:53 -0000 1.185
+++ kjs_window.cpp 7 Nov 2005 20:52:09 -0000 1.186
@@ -80,30 +80,25 @@
// <cmath> and <math.h> the macros necessary for functions like
// isnan are not defined.
#include <cmath>
+using std::isnan;
-using namespace DOM::EventNames;
+using namespace DOM;
+using namespace EventNames;
-using DOM::AtomicString;
-using DOM::DocumentImpl;
-using DOM::DOMString;
-using DOM::ElementImpl;
-using DOM::EventImpl;
-using DOM::HTMLCollectionImpl;
-using DOM::HTMLDocumentImpl;
-using DOM::HTMLElementImpl;
-using DOM::NodeImpl;
-using DOM::Position;
-
-using khtml::TypingCommand;
-
-using KParts::ReadOnlyPart;
-using KParts::URLArgs;
-using KParts::WindowArgs;
+using namespace khtml;
-using std::isnan;
+using namespace KParts;
namespace KJS {
+class PausedTimeout {
+public:
+ int timerId;
+ int nextFireInterval;
+ int repeatInterval;
+ ScheduledAction *action;
+};
+
////////////////////// History Object ////////////////////////
class History : public ObjectImp {
@@ -1262,47 +1257,11 @@
return !m_part.isNull();
}
-int Window::installTimeout(const UString &handler, int t, bool singleShot)
-{
- return winq->installTimeout(handler, t, singleShot);
-}
-
-int Window::installTimeout(ValueImp *function, List &args, int t, bool singleShot)
-{
- return winq->installTimeout(function, args, t, singleShot);
-}
-
-void Window::clearTimeout(int timerId)
-{
- winq->clearTimeout(timerId);
-}
-
-#if APPLE_CHANGES
-bool Window::hasTimeouts()
-{
- return winq->hasTimeouts();
-}
-
-QMap<int, ScheduledAction*> *Window::pauseTimeouts(const void *key)
-{
- return winq->pauseTimeouts(key);
-}
-
-void Window::resumeTimeouts(QMap<int, ScheduledAction*> *sa, const void *key)
-{
- return winq->resumeTimeouts(sa, key);
-}
-#endif
-
void Window::scheduleClose()
{
kdDebug(6070) << "Window::scheduleClose window.close() " << m_part << endl;
Q_ASSERT(winq);
-#if APPLE_CHANGES
KWQ(m_part)->scheduleClose();
-#else
- QTimer::singleShot( 0, winq, SLOT( timeoutClose() ) );
-#endif
}
static bool shouldLoadAsEmptyDocument(const KURL &url)
@@ -2027,200 +1986,141 @@
docimpl->updateLayoutIgnorePendingStylesheets();
}
-
////////////////////// ScheduledAction ////////////////////////
-ScheduledAction::ScheduledAction(ObjectImp *_func, List _args, bool _singleShot)
+void ScheduledAction::execute(Window *window)
{
- //kdDebug(6070) << "ScheduledAction::ScheduledAction(isFunction) " << this << endl;
- func = _func;
- args = _args;
- isFunction = true;
- singleShot = _singleShot;
-}
-
-ScheduledAction::ScheduledAction(const QString &_code, bool _singleShot)
-{
- //kdDebug(6070) << "ScheduledAction::ScheduledAction(!isFunction) " << this << endl;
- //func = 0;
- //args = 0;
- code = _code;
- isFunction = false;
- singleShot = _singleShot;
-}
+ if (!window->m_part)
+ return;
+ ScriptInterpreter *interpreter = static_cast<ScriptInterpreter *>(KJSProxy::proxy(window->m_part)->interpreter());
-void ScheduledAction::execute(Window *window)
-{
- ScriptInterpreter *interpreter = static_cast<ScriptInterpreter *>(KJSProxy::proxy(window->m_part)->interpreter());
+ interpreter->setProcessingTimerCallback(true);
- interpreter->setProcessingTimerCallback(true);
-
- //kdDebug(6070) << "ScheduledAction::execute " << this << endl;
- if (isFunction) {
- if (func->implementsCall()) {
- // #### check this
- Q_ASSERT(window->m_part);
- if (window->m_part) {
- Interpreter *interpreter = KJSProxy::proxy(window->m_part)->interpreter();
- ExecState *exec = interpreter->globalExec();
- Q_ASSERT(window == interpreter->globalObject());
- ObjectImp *obj(window);
- InterpreterLock lock;
- func->call(exec, obj, args); // note that call() creates its own execution state for the func call
- if (exec->hadException()) {
- char *message = exec->exception()->toObject(exec)->get(exec, messagePropertyName)->toString(exec).ascii();
- int lineNumber = exec->exception()->toObject(exec)->get(exec, "line")->toInt32(exec);
- if (Interpreter::shouldPrintExceptions()) {
- printf("(timer):%s\n", message);
-
- KWQ(window->m_part)->addMessageToConsole(message, lineNumber, QString());
- }
- exec->clearException();
+ if (m_func) {
+ if (m_func->isObject() && static_cast<ObjectImp *>(m_func.get())->implementsCall()) {
+ ExecState *exec = interpreter->globalExec();
+ assert(window == interpreter->globalObject());
+ InterpreterLock lock;
+ static_cast<ObjectImp *>(m_func.get())->call(exec, window, m_args);
+ if (exec->hadException()) {
+ ObjectImp *exception = exec->exception()->toObject(exec);
+ exec->clearException();
+ QString message = exception->get(exec, messagePropertyName)->toString(exec).qstring();
+ int lineNumber = exception->get(exec, "line")->toInt32(exec);
+ if (Interpreter::shouldPrintExceptions())
+ printf("(timer):%s\n", message.utf8().data());
+ KWQ(window->m_part)->addMessageToConsole(message, lineNumber, QString());
+ }
}
- }
- }
- } else
- window->m_part->executeScript(code);
+ } else
+ window->m_part->executeScript(m_code);
- // Update our document's rendering following the execution of the timeout callback.
- if (DocumentImpl *doc = window->m_part->xmlDocImpl())
- doc->updateRendering();
+ // Update our document's rendering following the execution of the timeout callback.
+ // FIXME: Why? Why not other documents, for example?
+ DocumentImpl *doc = window->m_part->xmlDocImpl();
+ if (doc)
+ doc->updateRendering();
- interpreter->setProcessingTimerCallback(false);
+ interpreter->setProcessingTimerCallback(false);
}
////////////////////// WindowQObject ////////////////////////
WindowQObject::WindowQObject(Window *w)
- : parent(w)
+ : m_parent(w)
{
- //kdDebug(6070) << "WindowQObject::WindowQObject " << this << endl;
- part = parent->m_part;
- connect( parent->m_part, SIGNAL( destroyed() ),
- this, SLOT( parentDestroyed() ) );
-}
-
-WindowQObject::~WindowQObject()
-{
- //kdDebug(6070) << "WindowQObject::~WindowQObject " << this << endl;
- parentDestroyed(); // reuse same code
+ connect(w->m_part, SIGNAL(destroyed()), this, SLOT(parentDestroyed()));
}
void WindowQObject::parentDestroyed()
{
- //kdDebug(6070) << "WindowQObject::parentDestroyed " << this << " we have " << scheduledActions.count() << " actions in the map" << endl;
- killTimers();
- QMapIterator<int,ScheduledAction*> it;
- for (it = scheduledActions.begin(); it != scheduledActions.end(); ++it) {
- ScheduledAction *action = *it;
- //kdDebug(6070) << "WindowQObject::parentDestroyed deleting action " << action << endl;
- delete action;
- }
- scheduledActions.clear();
+ killTimers();
+ for (QMapIterator<int, ScheduledAction *> it = m_timeouts.begin(); it != m_timeouts.end(); ++it)
+ delete *it;
+ m_timeouts.clear();
}
-int WindowQObject::installTimeout(const UString &handler, int t, bool singleShot)
+int WindowQObject::installTimeout(const UString& handler, int t, bool singleShot)
{
- //kdDebug(6070) << "WindowQObject::installTimeout " << this << " " << handler.ascii() << endl;
- int id = startTimer(t);
- ScheduledAction *action = new ScheduledAction(handler.qstring(),singleShot);
- scheduledActions.insert(id, action);
- //kdDebug(6070) << this << " got id=" << id << " action=" << action << " - now having " << scheduledActions.count() << " actions"<<endl;
- return id;
+ int id = startTimer(t);
+ ScheduledAction *action = new ScheduledAction(handler.qstring(), singleShot);
+ m_timeouts.insert(id, action);
+ return id;
}
-int WindowQObject::installTimeout(ValueImp *func, List args, int t, bool singleShot)
+int WindowQObject::installTimeout(ValueImp *func, const List& args, int t, bool singleShot)
{
- ObjectImp *objFunc = static_cast<ObjectImp *>(func);
- int id = startTimer(t);
- scheduledActions.insert(id, new ScheduledAction(objFunc,args,singleShot));
- return id;
+ int id = startTimer(t);
+ m_timeouts.insert(id, new ScheduledAction(func, args, singleShot));
+ return id;
}
-QMap<int, ScheduledAction*> *WindowQObject::pauseTimeouts(const void *key)
+PausedTimeouts *WindowQObject::pauseTimeouts()
{
- QMapIterator<int,ScheduledAction*> it;
-
- QMap<int, ScheduledAction*>*pausedActions = new QMap<int, ScheduledAction*>;
- for (it = scheduledActions.begin(); it != scheduledActions.end(); ++it) {
+ size_t count = m_timeouts.count();
+ if (count == 0)
+ return 0;
+ PausedTimeout *t = new PausedTimeout [count];
+ PausedTimeouts *result = new PausedTimeouts(t, count);
+ for (QMapIterator<int, ScheduledAction *> it = m_timeouts.begin(); it != m_timeouts.end(); ++it) {
int timerId = it.key();
- pauseTimer (timerId, key);
- pausedActions->insert(timerId, it.data());
+ timerIntervals(timerId, t->nextFireInterval, t->repeatInterval);
+ t->timerId = timerId;
+ t->action = it.data();
+ ++t;
+ killTimer(timerId);
}
- scheduledActions.clear();
- return pausedActions;
+ m_timeouts.clear();
+ return result;
}
-void WindowQObject::resumeTimeouts(QMap<int, ScheduledAction*> *sa, const void *key)
+void WindowQObject::resumeTimeouts(PausedTimeouts *timeouts)
{
- QMapIterator<int,ScheduledAction*> it;
- for (it = sa->begin(); it != sa->end(); ++it) {
- int timerId = it.key();
- scheduledActions.insert(timerId, it.data());
+ if (!timeouts)
+ return;
+ size_t count = timeouts->numTimeouts();
+ PausedTimeout *array = timeouts->takeTimeouts();
+ for (size_t i = 0; i != count; ++i) {
+ int timerId = array[i].timerId;
+ m_timeouts.insert(timerId, array[i].action);
+ restartTimer(timerId, array[i].nextFireInterval, array[i].repeatInterval);
}
- sa->clear();
- resumeTimers (key, this);
+ delete [] array;
}
void WindowQObject::clearTimeout(int timerId, bool delAction)
{
- //kdDebug(6070) << "WindowQObject::clearTimeout " << this << " timerId=" << timerId << " delAction=" << delAction << endl;
- killTimer(timerId);
- if (delAction) {
- QMapIterator<int,ScheduledAction*> it = scheduledActions.find(timerId);
- if (it != scheduledActions.end()) {
- ScheduledAction *action = *it;
- scheduledActions.remove(it);
- delete action;
+ killTimer(timerId);
+ if (delAction) {
+ QMapIterator<int, ScheduledAction *> it = m_timeouts.find(timerId);
+ if (it != m_timeouts.end()) {
+ delete *it;
+ m_timeouts.remove(it);
+ }
}
- }
}
void WindowQObject::timerEvent(QTimerEvent *e)
{
- QMapIterator<int,ScheduledAction*> it = scheduledActions.find(e->timerId());
- if (it != scheduledActions.end()) {
+ QMapIterator<int, ScheduledAction *> it = m_timeouts.find(e->timerId());
ScheduledAction *action = *it;
- bool singleShot = action->singleShot;
- //kdDebug(6070) << "WindowQObject::timerEvent " << this << " action=" << action << " singleShot:" << singleShot << endl;
+ bool singleShot = action->singleShot();
- // remove single shots installed by setTimeout()
- if (singleShot)
- {
- clearTimeout(e->timerId(),false);
- scheduledActions.remove(it);
+ // remove single shots before executing
+ if (singleShot) {
+ clearTimeout(e->timerId(), false);
+ m_timeouts.remove(it);
}
-
- if (!parent->part().isNull())
- action->execute(parent);
- // It is important to test singleShot and not action->singleShot here - the
- // action could have been deleted already if not single shot and if the
+ action->execute(m_parent);
+
+ // It is important not to use action->singleShot here.
+ // The action could have been deleted already if not single shot the
// JS code called by execute() calls clearTimeout().
if (singleShot)
- delete action;
- } else
- kdWarning(6070) << "WindowQObject::timerEvent this=" << this << " timer " << e->timerId()
- << " not found (" << scheduledActions.count() << " actions in map)" << endl;
-}
-
-void WindowQObject::timeoutClose()
-{
- if (!parent->part().isNull())
- {
- //kdDebug(6070) << "WindowQObject::timeoutClose -> closing window" << endl;
- delete parent->m_part;
- }
-}
-
-#if APPLE_CHANGES
-bool WindowQObject::hasTimeouts()
-{
- return scheduledActions.count();
+ delete action;
}
-#endif
-
const ClassInfo FrameArray::info = { "FrameArray", 0, &FrameArrayTable, 0 };
@@ -2231,7 +2131,6 @@
@end
*/
-
ValueImp *FrameArray::getValueProperty(ExecState *exec, int token)
{
switch (token) {
@@ -2808,6 +2707,17 @@
/////////////////////////////////////////////////////////////////////////////
+PausedTimeouts::~PausedTimeouts()
+{
+ PausedTimeout *array = m_array;
+ if (!array)
+ return;
+ size_t count = m_length;
+ for (size_t i = 0; i != count; ++i)
+ delete array[i].action;
+ delete [] array;
+}
+
} // namespace KJS
#include "kjs_window.moc"
1.55 +73 -58 WebCore/khtml/ecma/kjs_window.h
Index: kjs_window.h
===================================================================
RCS file: /cvs/root/WebCore/khtml/ecma/kjs_window.h,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -r1.54 -r1.55
--- kjs_window.h 27 Oct 2005 22:34:47 -0000 1.54
+++ kjs_window.h 7 Nov 2005 20:52:09 -0000 1.55
@@ -40,17 +40,57 @@
namespace KJS {
- class WindowFunc;
- class WindowQObject;
- class Location;
- class Selection;
- class BarInfo;
- class History;
- class FrameArray;
- class JSEventListener;
- class JSUnprotectedEventListener;
- class JSLazyEventListener;
- class ScheduledAction;
+ class BarInfo;
+ class FrameArray;
+ class History;
+ class JSEventListener;
+ class JSLazyEventListener;
+ class JSUnprotectedEventListener;
+ class Location;
+ class PausedTimeout;
+ class ScheduledAction;
+ class Selection;
+ class Window;
+ class WindowFunc;
+
+ class PausedTimeouts {
+ public:
+ PausedTimeouts(PausedTimeout *a, size_t length) : m_array(a), m_length(length) { }
+ ~PausedTimeouts();
+
+ size_t numTimeouts() const { return m_length; }
+ PausedTimeout *takeTimeouts()
+ { PausedTimeout *a = m_array; m_array = 0; return a; }
+
+ private:
+ PausedTimeout *m_array;
+ size_t m_length;
+
+ PausedTimeouts(const PausedTimeouts&);
+ PausedTimeouts& operator=(const PausedTimeouts&);
+ };
+
+ class WindowQObject : public QObject {
+ Q_OBJECT
+ public:
+ WindowQObject(Window *);
+ ~WindowQObject() { parentDestroyed(); }
+
+ int installTimeout(const UString &handler, int interval, bool singleShot);
+ int installTimeout(ValueImp *function, const List &, int interval, bool singleShot);
+ void clearTimeout(int timerId, bool delAction = true);
+
+ PausedTimeouts *pauseTimeouts();
+ void resumeTimeouts(PausedTimeouts *);
+
+ private slots:
+ void parentDestroyed();
+ private:
+ virtual void timerEvent(QTimerEvent *);
+
+ Window *m_parent;
+ QMap<int, ScheduledAction *> m_timeouts;
+ };
class Screen : public ObjectImp {
public:
@@ -98,21 +138,19 @@
ValueImp *getValueProperty(ExecState *exec, int token) const;
virtual void put(ExecState *exec, const Identifier &propertyName, ValueImp *value, int attr = None);
virtual bool toBoolean(ExecState *exec) const;
- int installTimeout(const UString &handler, int t, bool singleShot);
- int installTimeout(ValueImp *function, List &args, int t, bool singleShot);
- void clearTimeout(int timerId);
-#ifdef APPLE_CHANGES
- bool hasTimeouts();
- QMap<int, ScheduledAction*> *pauseTimeouts(const void *key);
- void resumeTimeouts(QMap<int, ScheduledAction*>*sa, const void *key);
+
+ int installTimeout(const UString &handler, int t, bool singleShot) { return winq->installTimeout(handler, t, singleShot); }
+ int installTimeout(ValueImp *function, List &args, int t, bool singleShot) { return winq->installTimeout(function, args, t, singleShot); }
+ void clearTimeout(int timerId) { winq->clearTimeout(timerId); }
+ PausedTimeouts *pauseTimeouts() { return winq->pauseTimeouts(); }
+ void resumeTimeouts(PausedTimeouts *t) { winq->resumeTimeouts(t); }
KJS::Interpreter *interpreter() const;
- static bool isSafeScript (const KJS::ScriptInterpreter *origin, const KJS::ScriptInterpreter *target);
-#endif
void scheduleClose();
bool isSafeScript(ExecState *exec) const;
+ static bool isSafeScript(const ScriptInterpreter *origin, const ScriptInterpreter *target);
Location *location() const;
Selection *selection() const;
BarInfo *locationbar(ExecState *exec) const;
@@ -186,44 +224,21 @@
* time interval, either once or repeatedly. Used for window.setTimeout()
* and window.setInterval()
*/
- class ScheduledAction {
- public:
- ScheduledAction(ObjectImp *_func, List _args, bool _singleShot);
- ScheduledAction(const QString &_code, bool _singleShot);
- void execute(Window *window);
-
- ProtectedPtr<ObjectImp> func;
- List args;
- QString code;
- bool isFunction;
- bool singleShot;
- };
-
- class WindowQObject : public QObject {
- Q_OBJECT
- public:
- WindowQObject(Window *w);
- ~WindowQObject();
- int installTimeout(const UString &handler, int t, bool singleShot);
- int installTimeout(ValueImp *func, List args, int t, bool singleShot);
- void clearTimeout(int timerId, bool delAction = true);
-#ifdef APPLE_CHANGES
- bool hasTimeouts();
- QMap<int, ScheduledAction*> *WindowQObject::pauseTimeouts(const void *key);
- void WindowQObject::resumeTimeouts(QMap<int, ScheduledAction*> *sa, const void *key);
-#endif
-
- public slots:
- void timeoutClose();
- protected slots:
- void parentDestroyed();
- protected:
- void timerEvent(QTimerEvent *e);
- private:
- Window *parent;
- KHTMLPart *part; // not guarded, may be dangling
- QMap<int, ScheduledAction*> scheduledActions;
- };
+ class ScheduledAction {
+ public:
+ ScheduledAction(ValueImp *func, const List& args, bool singleShot)
+ : m_func(func), m_args(args), m_singleShot(singleShot) { }
+ ScheduledAction(const QString& code, bool singleShot)
+ : m_code(code), m_singleShot(singleShot) { }
+ void execute(Window *);
+ bool singleShot() const { return m_singleShot; }
+
+ private:
+ ProtectedPtr<ValueImp> m_func;
+ List m_args;
+ QString m_code;
+ bool m_singleShot;
+ };
class Location : public ObjectImp {
public:
1.231 +3 -2 WebCore/kwq/KWQKHTMLPart.h
Index: KWQKHTMLPart.h
===================================================================
RCS file: /cvs/root/WebCore/kwq/KWQKHTMLPart.h,v
retrieving revision 1.230
retrieving revision 1.231
diff -u -r1.230 -r1.231
--- KWQKHTMLPart.h 2 Nov 2005 18:54:01 -0000 1.230
+++ KWQKHTMLPart.h 7 Nov 2005 20:52:10 -0000 1.231
@@ -61,6 +61,7 @@
}
namespace KJS {
+ class PausedTimeouts;
class SavedProperties;
class SavedBuiltins;
class ScheduledAction;
@@ -160,8 +161,8 @@
void unfocusWindow();
- QMap<int, KJS::ScheduledAction*> *pauseActions(const void *key);
- void resumeActions(QMap<int, KJS::ScheduledAction*> *actions, const void *key);
+ KJS::PausedTimeouts *pauseTimeouts();
+ void resumeTimeouts(KJS::PausedTimeouts *);
bool canCachePage();
void saveWindowProperties(KJS::SavedProperties *windowProperties);
1.685 +30 -104 WebCore/kwq/KWQKHTMLPart.mm
Index: KWQKHTMLPart.mm
===================================================================
RCS file: /cvs/root/WebCore/kwq/KWQKHTMLPart.mm,v
retrieving revision 1.684
retrieving revision 1.685
diff -u -r1.684 -r1.685
--- KWQKHTMLPart.mm 3 Nov 2005 19:12:06 -0000 1.684
+++ KWQKHTMLPart.mm 7 Nov 2005 20:52:10 -0000 1.685
@@ -88,87 +88,18 @@
#undef _KWQ_TIMING
-using namespace DOM::EventNames;
-using namespace DOM::HTMLNames;
+using namespace DOM;
+using namespace EventNames;
+using namespace HTMLNames;
-using DOM::AtomicString;
-using DOM::ClipboardEventImpl;
-using DOM::DocumentFragmentImpl;
-using DOM::DocumentImpl;
-using DOM::DocumentMarker;
-using DOM::DOMString;
-using DOM::ElementImpl;
-using DOM::EventImpl;
-using DOM::HTMLDocumentImpl;
-using DOM::HTMLElementImpl;
-using DOM::HTMLFormElementImpl;
-using DOM::HTMLFrameElementImpl;
-using DOM::HTMLGenericFormElementImpl;
-using DOM::HTMLTableCellElementImpl;
-using DOM::Node;
-using DOM::NodeImpl;
-using DOM::Position;
-using DOM::Range;
-using DOM::RangeImpl;
-using DOM::TextImpl;
-
-using khtml::Cache;
-using khtml::CharacterIterator;
-using khtml::ChildFrame;
-using khtml::Decoder;
-using khtml::DashboardRegionValue;
-using khtml::EditCommandPtr;
-using khtml::endOfWord;
-using khtml::findPlainText;
-using khtml::FocusState;
-using khtml::InlineTextBox;
-using khtml::LeftWordIfOnBoundary;
-using khtml::MouseDoubleClickEvent;
-using khtml::MouseMoveEvent;
-using khtml::MousePressEvent;
-using khtml::MouseReleaseEvent;
-using khtml::parseURL;
-using khtml::PRE;
-using khtml::RenderCanvas;
-using khtml::RenderImage;
-using khtml::RenderLayer;
-using khtml::RenderListItem;
-using khtml::RenderObject;
-using khtml::RenderStyle;
-using khtml::RenderTableCell;
-using khtml::RenderText;
-using khtml::theme;
-using khtml::RenderWidget;
-using khtml::RightWordIfOnBoundary;
-using khtml::SelectionController;
-using khtml::SELECT_IGNORE;
-using khtml::setEnd;
-using khtml::setStart;
-using khtml::ShadowData;
-using khtml::startOfWord;
-using khtml::startVisiblePosition;
-using khtml::StyleDashboardRegion;
-using khtml::TextIterator;
-using khtml::DOWNSTREAM;
-using khtml::VP_UPSTREAM_IF_POSSIBLE;
-using khtml::VISIBLE;
-using khtml::VisiblePosition;
-using khtml::WordAwareIterator;
-
-using KIO::Job;
-
-using KJS::Interpreter;
-using KJS::InterpreterLock;
-using KJS::Location;
-using KJS::SavedBuiltins;
-using KJS::SavedProperties;
-using KJS::ScheduledAction;
-using KJS::Window;
+using namespace KJS;
+using namespace Bindings;
-using KJS::Bindings::Instance;
+using namespace khtml;
-using KParts::ReadOnlyPart;
-using KParts::URLArgs;
+using namespace KIO;
+
+using namespace KParts;
NSEvent *KWQKHTMLPart::_currentEvent = nil;
@@ -1147,11 +1078,13 @@
KWQ_BLOCK_EXCEPTIONS;
if (d->m_redirectionTimer.isActive()) {
+ NSDate *fireDate = [[NSDate alloc] initWithTimeIntervalSinceReferenceDate:d->m_redirectionTimer.fireDate()];
[_bridge reportClientRedirectToURL:KURL(d->m_redirectURL).getNSURL()
delay:d->m_delayRedirect
- fireDate:[d->m_redirectionTimer.getNSTimer() fireDate]
+ fireDate:fireDate
lockHistory:d->m_redirectLockHistory
isJavaScriptFormAction:d->m_executingJavaScriptFormAction];
+ [fireDate release];
} else {
[_bridge reportClientRedirectCancelled:d->m_cancelWithLoadInProgress];
}
@@ -1472,24 +1405,22 @@
[_bridge windowObjectCleared];
}
-QMap<int, ScheduledAction*> *KWQKHTMLPart::pauseActions(const void *key)
+PausedTimeouts *KWQKHTMLPart::pauseTimeouts()
{
if (d->m_doc && d->m_jscript) {
Window *w = Window::retrieveWindow(this);
- if (w && w->hasTimeouts()) {
- return w->pauseTimeouts(key);
- }
+ if (w)
+ return w->pauseTimeouts();
}
return 0;
}
-void KWQKHTMLPart::resumeActions(QMap<int, ScheduledAction*> *actions, const void *key)
+void KWQKHTMLPart::resumeTimeouts(PausedTimeouts *t)
{
if (d->m_doc && d->m_jscript && d->m_bJScriptEnabled) {
Window *w = Window::retrieveWindow(this);
- if (w) {
- w->resumeTimeouts(actions, key);
- }
+ if (w)
+ w->resumeTimeouts(t);
}
}
@@ -1572,14 +1503,13 @@
SavedProperties *windowProperties = [state windowProperties];
SavedProperties *locationProperties = [state locationProperties];
SavedBuiltins *interpreterBuiltins = [state interpreterBuiltins];
- QMap<int, ScheduledAction*> *actions = [state pausedActions];
+ PausedTimeouts *timeouts = [state pausedTimeouts];
cancelRedirection();
// We still have to close the previous part page.
- if (!d->m_restored){
+ if (!d->m_restored)
closeURL();
- }
d->m_bComplete = false;
@@ -1587,13 +1517,12 @@
d->m_bLoadEventEmitted = true;
// delete old status bar msg's from kjs (if it _was_ activated on last URL)
- if( d->m_bJScriptEnabled )
- {
+ if (d->m_bJScriptEnabled) {
d->m_kjsStatusBarText = QString::null;
d->m_kjsDefaultStatusBarText = QString::null;
}
- ASSERT (url);
+ ASSERT(url);
m_url = *url;
@@ -1627,27 +1556,24 @@
d->m_mousePressNode.reset(mousePressNode);
Decoder *decoder = doc->decoder();
- if (decoder) {
+ if (decoder)
decoder->ref();
- }
- if (d->m_decoder) {
+ if (d->m_decoder)
d->m_decoder->deref();
- }
d->m_decoder = decoder;
- doc->setParseMode ([state parseMode]);
+ doc->setParseMode([state parseMode]);
updatePolicyBaseURL();
{ // scope the lock
InterpreterLock lock;
- restoreWindowProperties (windowProperties);
- restoreLocationProperties (locationProperties);
- restoreInterpreterBuiltins (*interpreterBuiltins);
+ restoreWindowProperties(windowProperties);
+ restoreLocationProperties(locationProperties);
+ restoreInterpreterBuiltins(*interpreterBuiltins);
}
- if (actions)
- resumeActions (actions, state);
+ resumeTimeouts(timeouts);
checkCompleted();
}
@@ -4232,7 +4158,7 @@
int exception = 0;
ASSERT(!range || range->startContainer(exception) == range->endContainer(exception));
- ASSERT(!range || range->collapsed(exception) || range->startContainer(exception)->nodeType() == Node::TEXT_NODE);
+ ASSERT(!range || range->collapsed(exception) || range->startContainer(exception)->nodeType() == DOM::Node::TEXT_NODE);
if (attributes == nil) {
m_markedTextUsesUnderlines = false;
1.37 +20 -33 WebCore/kwq/KWQObject.h
Index: KWQObject.h
===================================================================
RCS file: /cvs/root/WebCore/kwq/KWQObject.h,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- KWQObject.h 18 May 2005 21:10:26 -0000 1.36
+++ KWQObject.h 7 Nov 2005 20:52:11 -0000 1.37
@@ -26,14 +26,10 @@
#ifndef QOBJECT_H_
#define QOBJECT_H_
-#include "KWQDef.h"
-#include "KWQSignal.h"
-
-#include "KWQNamespace.h"
-#include "KWQString.h"
#include "KWQEvent.h"
-#include "KWQStringList.h"
#include "KWQPtrList.h"
+#include "KWQSignal.h"
+#include "KWQStringList.h"
#define slots : public
#define SLOT(x) "SLOT:" #x
@@ -43,36 +39,30 @@
#define Q_OBJECT
#define Q_PROPERTY(text)
+class QBitmap;
+class QBrush;
+class QColor;
+class QColorGroup;
class QEvent;
+class QFont;
+class QFontMetrics;
+class QImage;
+class QMovie;
class QPaintDevice;
class QPaintDeviceMetrics;
-class QWidget;
-class QColor;
-class QColorGroup;
-class QPalette;
class QPainter;
+class QPalette;
+class QRect;
class QRegion;
class QSize;
class QSizePolicy;
-class QRect;
-class QFont;
-class QFontMetrics;
-class QBrush;
-class QBitmap;
-class QMovie;
class QTimer;
-class QImage;
class QVariant;
+class QWidget;
class KWQGuardedPtrBase;
class KWQSignal;
-#ifdef __OBJC__
- at class NSTimer;
-#else
-class NSTimer;
-#endif
-
class QObject : public Qt {
public:
QObject(QObject *parent = 0, const char *name = 0);
@@ -85,12 +75,11 @@
bool inherits(const char *className) const;
- int startTimer(int);
- void killTimer(int);
+ int startTimer(int interval);
+ void killTimer(int timerId);
void killTimers();
- void pauseTimer(int _timerId, const void *key);
- void resumeTimers(const void *key, QObject *target);
- static void clearPausedTimers (const void *key);
+ void timerIntervals(int timerId, int& nextFireInterval, int& repeatInterval) const;
+ void restartTimer(int timerId, int nextFireInterval, int repeatInterval);
virtual void timerEvent(QTimerEvent *);
@@ -117,8 +106,6 @@
virtual bool isQScrollView() const;
private:
- void _addTimer(NSTimer *timer, int _timerId);
-
// no copying or assignment
QObject(const QObject &);
QObject &operator=(const QObject &);
@@ -145,11 +132,11 @@
class KWQObjectSenderScope
{
public:
- KWQObjectSenderScope(const QObject *);
- ~KWQObjectSenderScope();
+ KWQObjectSenderScope(const QObject *o) : m_savedSender(QObject::_sender) { QObject::_sender = o; }
+ ~KWQObjectSenderScope() { QObject::_sender = m_savedSender; }
private:
- const QObject *_savedSender;
+ const QObject *m_savedSender;
};
#endif
1.49 +139 -224 WebCore/kwq/KWQObject.mm
Index: KWQObject.mm
===================================================================
RCS file: /cvs/root/WebCore/kwq/KWQObject.mm,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -r1.48 -r1.49
--- KWQObject.mm 3 Oct 2005 21:13:06 -0000 1.48
+++ KWQObject.mm 7 Nov 2005 20:52:11 -0000 1.49
@@ -28,48 +28,53 @@
#import "KWQVariant.h"
#import <kxmlcore/Assertions.h>
+#import <kxmlcore/FastMalloc.h>
-// The Foundation-level Cocoa calls here (NSTimer, NSDate, NSArray,
-// NSDictionary) should be exception-free, so no need to block
-// exceptions.
+struct KWQObjectTimer {
+ QObject *target;
+ int timerId;
+ CFRunLoopTimerRef runLoopTimer; // non-0 for running timers
+ CFIndex deferredTimerArrayIndex; // kCFNotFound if not deferred
+};
const QObject *QObject::_sender;
bool QObject::_defersTimers;
static CFMutableDictionaryRef timerDictionaries;
-static CFMutableDictionaryRef allPausedTimers;
-static NSMutableArray *deferredTimers;
+static CFMutableArrayRef deferredTimers;
static bool deferringTimers;
+static CFRunLoopTimerRef sendDeferredTimerEventsTimer;
- at interface KWQObjectTimerTarget : NSObject
+static int lastTimerIdUsed;
+
+QObject::QObject(QObject *parent, const char *name)
+ : _signalListHead(0), _signalsBlocked(false)
+ , _destroyed(this, SIGNAL(destroyed()))
+ , _eventFilterObject(0)
{
- at public
- QObject *target;
- int timerId;
- NSTimeInterval remainingTime;
+ _guardedPtrDummyList.append(this);
}
-- initWithQObject:(QObject *)object timerId:(int)timerId;
-- (void)timerFired;
-
- at end
+QObject::~QObject()
+{
+ _destroyed.call();
+ ASSERT(_signalListHead == &_destroyed);
+ killTimers();
+}
KWQSignal *QObject::findSignal(const char *signalName) const
{
- for (KWQSignal *signal = _signalListHead; signal; signal = signal->_next) {
- if (KWQNamesMatch(signalName, signal->_name)) {
+ for (KWQSignal *signal = _signalListHead; signal; signal = signal->_next)
+ if (KWQNamesMatch(signalName, signal->_name))
return signal;
- }
- }
return 0;
}
void QObject::connect(const QObject *sender, const char *signalName, const QObject *receiver, const char *member)
{
- // FIXME: Assert that sender is not NULL rather than doing the if statement.
- if (!sender) {
+ // FIXME: Assert that sender is not 0 rather than doing the if statement, then fix callers who call with 0.
+ if (!sender)
return;
- }
KWQSignal *signal = sender->findSignal(signalName);
if (!signal) {
@@ -83,7 +88,7 @@
&& !KWQNamesMatch(member, SLOT(slotShowDocument(const QString &, const QString &)))
&& !KWQNamesMatch(member, SLOT(slotViewCleared())) // FIXME: Should implement this one!
)
- ERROR("connecting member %s to signal %s, but that signal was not found", member, signalName);
+ ERROR("connecting member %s to signal %s, but that signal was not found", member, signalName);
#endif
return;
}
@@ -92,274 +97,184 @@
void QObject::disconnect(const QObject *sender, const char *signalName, const QObject *receiver, const char *member)
{
- // FIXME: Assert that sender is not NULL rather than doing the if statement.
+ // FIXME: Assert that sender is not 0 rather than doing the if statement, then fix callers who call with 0.
if (!sender)
return;
KWQSignal *signal = sender->findSignal(signalName);
if (!signal) {
- // FIXME: ERROR
+ // FIXME: Put a call to ERROR here and clean up callers who do this.
return;
}
signal->disconnect(KWQSlot(const_cast<QObject *>(receiver), member));
}
-KWQObjectSenderScope::KWQObjectSenderScope(const QObject *o)
- : _savedSender(QObject::_sender)
+void QObject::timerEvent(QTimerEvent *)
{
- QObject::_sender = o;
}
-KWQObjectSenderScope::~KWQObjectSenderScope()
-{
- QObject::_sender = _savedSender;
-}
-
-QObject::QObject(QObject *parent, const char *name)
- : _signalListHead(0), _signalsBlocked(false)
- , _destroyed(this, SIGNAL(destroyed()))
- , _eventFilterObject(0)
+bool QObject::event(QEvent *)
{
- _guardedPtrDummyList.append(this);
+ return false;
}
-QObject::~QObject()
+static void timerFired(CFRunLoopTimerRef runLoopTimer, void *info)
{
- _destroyed.call();
- ASSERT(_signalListHead == &_destroyed);
- killTimers();
+ KWQObjectTimer *timer = static_cast<KWQObjectTimer *>(info);
+ if (deferringTimers) {
+ if (timer->deferredTimerArrayIndex == kCFNotFound) {
+ if (!deferredTimers)
+ deferredTimers = CFArrayCreateMutable(0, 0, 0);
+ timer->deferredTimerArrayIndex = CFArrayGetCount(deferredTimers);
+ CFArrayAppendValue(deferredTimers, timer);
+ }
+ } else {
+ QTimerEvent event(timer->timerId);
+ timer->target->timerEvent(&event);
+ }
}
-void QObject::timerEvent(QTimerEvent *te)
+int QObject::startTimer(int interval)
{
+ int timerId = ++lastTimerIdUsed;
+ restartTimer(timerId, interval, interval);
+ return timerId;
}
-bool QObject::event(QEvent *)
+void QObject::restartTimer(int timerId, int nextFireInterval, int repeatInterval)
{
- return false;
-}
+ ASSERT(timerId > 0);
+ ASSERT(timerId <= lastTimerIdUsed);
-void QObject::pauseTimer (int _timerId, const void *key)
-{
- NSMutableDictionary *timers = (NSMutableDictionary *)CFDictionaryGetValue(timerDictionaries, this);
- NSNumber *timerId = [NSNumber numberWithInt:_timerId];
- NSTimer *timer = (NSTimer *)[timers objectForKey:timerId];
-
- if ([timer isValid]){
- KWQObjectTimerTarget *target = (KWQObjectTimerTarget *)[timer userInfo];
-
- if (target){
- NSDate *fireDate = [timer fireDate];
- NSTimeInterval remainingTime = [fireDate timeIntervalSinceDate: [NSDate date]];
-
- if (remainingTime < 0)
- remainingTime = DBL_EPSILON;
-
- if (allPausedTimers == NULL) {
- // The global targets dictionary itself leaks, but the contents are removed
- // when each timer fires or is killed.
- allPausedTimers = CFDictionaryCreateMutable(NULL, 0, NULL, &kCFTypeDictionaryValueCallBacks);
- }
-
- NSMutableArray *pausedTimers = (NSMutableArray *)CFDictionaryGetValue(allPausedTimers, key);
- if (pausedTimers == nil) {
- pausedTimers = [[NSMutableArray alloc] init];
- CFDictionarySetValue(allPausedTimers, key, pausedTimers);
- [pausedTimers release];
- }
-
- target->remainingTime = remainingTime;
- [pausedTimers addObject:target];
-
- [timer invalidate];
- [timers removeObjectForKey:timerId];
- }
- }
-}
+ if (!timerDictionaries)
+ timerDictionaries = CFDictionaryCreateMutable(0, 0, 0, &kCFTypeDictionaryValueCallBacks);
-void QObject::_addTimer(NSTimer *timer, int _timerId)
-{
- NSMutableDictionary *timers = (NSMutableDictionary *)CFDictionaryGetValue(timerDictionaries, this);
- if (timers == nil) {
- timers = [[NSMutableDictionary alloc] init];
+ CFMutableDictionaryRef timers = (CFMutableDictionaryRef)CFDictionaryGetValue(timerDictionaries, this);
+ if (!timers) {
+ timers = CFDictionaryCreateMutable(0, 0, 0, 0);
CFDictionarySetValue(timerDictionaries, this, timers);
- [timers release];
+ CFRelease(timers);
}
- [timers setObject:timer forKey:[NSNumber numberWithInt:_timerId]];
-}
-static int nextTimerID = 1;
+ ASSERT(!CFDictionaryGetValue(timers, reinterpret_cast<void *>(timerId)));
-void QObject::clearPausedTimers (const void *key)
-{
- if (allPausedTimers)
- CFDictionaryRemoveValue(allPausedTimers, key);
+ KWQObjectTimer *timer = static_cast<KWQObjectTimer *>(fastMalloc(sizeof(KWQObjectTimer)));
+ timer->target = this;
+ timer->timerId = timerId;
+ CFRunLoopTimerContext context = { 0, timer, 0, 0, 0 };
+ CFRunLoopTimerRef runLoopTimer = CFRunLoopTimerCreate(0, CFAbsoluteTimeGetCurrent() + nextFireInterval * 0.001,
+ repeatInterval * 0.001, 0, 0, timerFired, &context);
+ timer->runLoopTimer = runLoopTimer;
+ timer->deferredTimerArrayIndex = kCFNotFound;
+
+ CFDictionarySetValue(timers, reinterpret_cast<void *>(timerId), timer);
+
+ CFRunLoopAddTimer(CFRunLoopGetCurrent(), runLoopTimer, kCFRunLoopDefaultMode);
}
-void QObject::resumeTimers (const void *key, QObject *_target)
+void QObject::timerIntervals(int timerId, int& nextFireInterval, int& repeatInterval) const
{
- if (allPausedTimers == NULL) {
+ nextFireInterval = -1;
+ repeatInterval = -1;
+ if (!timerDictionaries)
return;
- }
-
- int maxId = MAX(0, nextTimerID);
-
- NSMutableArray *pausedTimers = (NSMutableArray *)CFDictionaryGetValue(allPausedTimers, key);
- if (pausedTimers == nil)
- return;
-
- int count = [pausedTimers count];
- while (count--){
- KWQObjectTimerTarget *target = [pausedTimers objectAtIndex: count];
- target->target = _target;
- NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:target->remainingTime
- target:target
- selector:@selector(timerFired)
- userInfo:target
- repeats:YES];
- [pausedTimers removeLastObject];
-
- maxId = MAX (maxId, target->timerId);
-
- _addTimer (timer, target->timerId);
- }
- nextTimerID = maxId+1;
-
- CFDictionaryRemoveValue(allPausedTimers, key);
+ CFMutableDictionaryRef timers = (CFMutableDictionaryRef)CFDictionaryGetValue(timerDictionaries, this);
+ if (!timers)
+ return;
+ KWQObjectTimer *timer = (KWQObjectTimer *)CFDictionaryGetValue(timers, reinterpret_cast<void *>(timerId));
+ if (!timer)
+ return;
+ nextFireInterval = (int)((CFRunLoopTimerGetNextFireDate(timer->runLoopTimer) - CFAbsoluteTimeGetCurrent()) * 1000);
+ repeatInterval = (int)(CFRunLoopTimerGetInterval(timer->runLoopTimer) * 1000);
}
-int QObject::startTimer(int milliseconds)
+static void deleteTimer(KWQObjectTimer *timer)
{
- if (timerDictionaries == NULL) {
- // The global timers dictionary itself lives forever, but the contents are removed
- // when each timer fires or is killed.
- timerDictionaries = CFDictionaryCreateMutable(NULL, 0, NULL, &kCFTypeDictionaryValueCallBacks);
- }
-
- NSMutableDictionary *timers = (NSMutableDictionary *)CFDictionaryGetValue(timerDictionaries, this);
- if (timers == nil) {
- timers = [[NSMutableDictionary alloc] init];
- CFDictionarySetValue(timerDictionaries, this, timers);
- [timers release];
- }
+ CFRunLoopTimerInvalidate(timer->runLoopTimer);
+ CFRelease(timer->runLoopTimer);
- KWQObjectTimerTarget *target = [[KWQObjectTimerTarget alloc] initWithQObject:this timerId:nextTimerID];
- NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:milliseconds / 1000.0
- target:target
- selector:@selector(timerFired)
- userInfo:target
- repeats:YES];
- [target release];
-
- _addTimer (timer, nextTimerID);
-
- return nextTimerID++;
+ CFIndex i = timer->deferredTimerArrayIndex;
+ if (i != kCFNotFound)
+ CFArraySetValueAtIndex(deferredTimers, i, 0);
+
+ fastFree(timer);
}
-void QObject::killTimer(int _timerId)
+void QObject::killTimer(int timerId)
{
- if (_timerId == 0) {
+ if (!timerDictionaries)
return;
- }
- if (timerDictionaries == NULL) {
+ CFMutableDictionaryRef timers = (CFMutableDictionaryRef)CFDictionaryGetValue(timerDictionaries, this);
+ if (!timers)
return;
- }
- NSMutableDictionary *timers = (NSMutableDictionary *)CFDictionaryGetValue(timerDictionaries, this);
- NSNumber *timerId = [NSNumber numberWithInt:_timerId];
- NSTimer *timer = (NSTimer *)[timers objectForKey:timerId];
- // Only try to remove the timer is it hasn't fired (and is therefore valid). It is NOT
- // permissible to reference a timer's userInfo if it is invalid.
- if ([timer isValid]){
- [deferredTimers removeObject:(KWQObjectTimerTarget *)[timer userInfo]];
- [timer invalidate];
- }
- [timers removeObjectForKey:timerId];
+ KWQObjectTimer *timer = (KWQObjectTimer *)CFDictionaryGetValue(timers, reinterpret_cast<void *>(timerId));
+ if (!timer)
+ return;
+ deleteTimer(timer);
+ CFDictionaryRemoveValue(timers, reinterpret_cast<void *>(timerId));
+}
+
+static void deleteOneTimer(const void *key, const void *value, void *context)
+{
+ deleteTimer((KWQObjectTimer *)value);
}
void QObject::killTimers()
{
- if (timerDictionaries == NULL) {
+ if (!timerDictionaries)
return;
- }
- NSMutableDictionary *timers = (NSMutableDictionary *)CFDictionaryGetValue(timerDictionaries, this);
- if (timers == nil) {
+ CFMutableDictionaryRef timers = (CFMutableDictionaryRef)CFDictionaryGetValue(timerDictionaries, this);
+ if (!timers)
return;
- }
- NSEnumerator *e = [timers keyEnumerator];
- NSNumber *timerId;
- while ((timerId = [e nextObject]) != nil) {
- killTimer([timerId intValue]);
- }
-
+ CFDictionaryApplyFunction(timers, deleteOneTimer, 0);
CFDictionaryRemoveValue(timerDictionaries, this);
}
+static void sendDeferredTimerEvent(const void *value, void *context)
+{
+ KWQObjectTimer *timer = (KWQObjectTimer *)value;
+ if (!timer)
+ return;
+ QTimerEvent event(timer->timerId);
+ timer->target->timerEvent(&event);
+}
+
+static void sendDeferredTimerEvents(CFRunLoopTimerRef, void *)
+{
+ CFRelease(sendDeferredTimerEventsTimer);
+ sendDeferredTimerEventsTimer = 0;
+
+ CFArrayRef timers = deferredTimers;
+ deferredTimers = 0;
+
+ CFArrayApplyFunction(timers, CFRangeMake(0, CFArrayGetCount(timers)), sendDeferredTimerEvent, 0);
+
+ CFRelease(timers);
+}
+
void QObject::setDefersTimers(bool defers)
{
if (defers) {
_defersTimers = true;
deferringTimers = true;
- [NSObject cancelPreviousPerformRequestsWithTarget:[KWQObjectTimerTarget class]];
+ if (sendDeferredTimerEventsTimer) {
+ CFRunLoopTimerInvalidate(sendDeferredTimerEventsTimer);
+ CFRelease(sendDeferredTimerEventsTimer);
+ sendDeferredTimerEventsTimer = 0;
+ }
return;
}
if (_defersTimers) {
_defersTimers = false;
if (deferringTimers) {
- [KWQObjectTimerTarget performSelector:@selector(stopDeferringTimers) withObject:nil afterDelay:0];
- }
- }
-}
-
- at implementation KWQObjectTimerTarget
-
-- initWithQObject:(QObject *)qo timerId:(int)t
-{
- [super init];
- target = qo;
- timerId = t;
- return self;
-}
-
-- (void)sendTimerEvent
-{
- QTimerEvent event(timerId);
- target->timerEvent(&event);
-}
-
-- (void)timerFired
-{
- if (deferringTimers) {
- if (deferredTimers == nil) {
- deferredTimers = [[NSMutableArray alloc] init];
+ sendDeferredTimerEventsTimer = CFRunLoopTimerCreate(0, CFAbsoluteTimeGetCurrent(),
+ 0, 0, 0, sendDeferredTimerEvents, 0);
+ CFRunLoopAddTimer(CFRunLoopGetCurrent(), sendDeferredTimerEventsTimer, kCFRunLoopDefaultMode);
}
- if (![deferredTimers containsObject:self]) {
- [deferredTimers addObject:self];
- }
- } else {
- [self sendTimerEvent];
}
}
-+ (void)stopDeferringTimers
-{
- ASSERT(deferringTimers);
- while ([deferredTimers count] != 0) {
- // remove before sending the timer event, in case the timer
- // callback cancels the timer - we don't want to remove too
- // much in that case.
- KWQObjectTimerTarget *timerTarget = [deferredTimers objectAtIndex:0];
- [timerTarget retain];
- [deferredTimers removeObjectAtIndex:0];
- [timerTarget sendTimerEvent];
- [timerTarget release];
- }
-
- deferringTimers = false;
-}
-
- at end
-
bool QObject::inherits(const char *className) const
{
if (strcmp(className, "KHTMLPart") == 0) {
1.8 +6 -14 WebCore/kwq/KWQPageState.h
Index: KWQPageState.h
===================================================================
RCS file: /cvs/root/WebCore/kwq/KWQPageState.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- KWQPageState.h 4 Mar 2005 23:59:10 -0000 1.7
+++ KWQPageState.h 7 Nov 2005 20:52:11 -0000 1.8
@@ -25,19 +25,12 @@
#import <Foundation/Foundation.h>
-#include <qmap.h>
-
-#include "kjs_window.h"
-#include "dom_docimpl.h"
-
-class KURL;
-
-namespace DOM {
- class DocumentImpl;
-}
+#import "dom_docimpl.h"
namespace KJS {
+ class SavedBuiltins;
class SavedProperties;
+ class PausedTimeouts;
}
@interface KWQPageState : NSObject
@@ -48,11 +41,11 @@
KJS::SavedProperties *windowProperties;
KJS::SavedProperties *locationProperties;
KJS::SavedBuiltins *interpreterBuiltins;
- QMap<int, KJS::ScheduledAction*> *pausedActions;
+ KJS::PausedTimeouts *pausedTimeouts;
DOM::DocumentImpl::ParseMode parseMode;
}
-- initWithDocument:(DOM::DocumentImpl *)doc URL:(const KURL &)u windowProperties:(KJS::SavedProperties *)wp locationProperties:(KJS::SavedProperties *)lp interpreterBuiltins:(KJS::SavedBuiltins *)ib;
+- initWithDocument:(DOM::DocumentImpl *)doc URL:(const KURL &)u windowProperties:(KJS::SavedProperties *)wp locationProperties:(KJS::SavedProperties *)lp interpreterBuiltins:(KJS::SavedBuiltins *)ib pausedTimeouts:(KJS::PausedTimeouts *)pt;
- (DOM::DocumentImpl *)document;
- (DOM::DocumentImpl::ParseMode)parseMode;
@@ -61,8 +54,7 @@
- (KJS::SavedProperties *)windowProperties;
- (KJS::SavedProperties *)locationProperties;
- (KJS::SavedBuiltins *)interpreterBuiltins;
-- (void)setPausedActions: (QMap<int, KJS::ScheduledAction*> *)pa;
-- (QMap<int, KJS::ScheduledAction*> *)pausedActions;
+- (KJS::PausedTimeouts *)pausedTimeouts;
- (void)invalidate;
@end
1.22 +31 -44 WebCore/kwq/KWQPageState.mm
Index: KWQPageState.mm
===================================================================
RCS file: /cvs/root/WebCore/kwq/KWQPageState.mm,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- KWQPageState.mm 3 Oct 2005 21:13:07 -0000 1.21
+++ KWQPageState.mm 7 Nov 2005 20:52:11 -0000 1.22
@@ -23,7 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
+#import "config.h"
#import "KWQPageState.h"
#import <JavaScriptCore/interpreter.h>
@@ -37,65 +37,50 @@
#import "KWQFoundationExtras.h"
#import "KWQKHTMLPart.h"
-using DOM::DocumentImpl;
+using namespace DOM;
-using khtml::RenderObject;
+using namespace khtml;
-using KJS::Interpreter;
-using KJS::InterpreterLock;
-using KJS::SavedProperties;
-using KJS::SavedBuiltins;
+using namespace KJS;
@implementation KWQPageState
-- initWithDocument:(DocumentImpl *)doc URL:(const KURL &)u windowProperties:(SavedProperties *)wp locationProperties:(SavedProperties *)lp interpreterBuiltins:(SavedBuiltins *)ib
+- initWithDocument:(DocumentImpl *)doc URL:(const KURL &)u windowProperties:(SavedProperties *)wp locationProperties:(SavedProperties *)lp interpreterBuiltins:(SavedBuiltins *)ib pausedTimeouts:(PausedTimeouts *)pt
{
[super init];
+
doc->ref();
document = doc;
- document->setInPageCache(YES);
- parseMode = document->parseMode();
- document->view()->ref();
- mousePressNode = static_cast<KWQKHTMLPart *>(document->part())->mousePressNode();
- if (mousePressNode) {
+ doc->setInPageCache(YES);
+ mousePressNode = static_cast<KWQKHTMLPart *>(doc->part())->mousePressNode();
+ if (mousePressNode)
mousePressNode->ref();
- }
URL = new KURL(u);
windowProperties = wp;
locationProperties = lp;
interpreterBuiltins = ib;
- return self;
-}
+ pausedTimeouts = pt;
+ parseMode = doc->parseMode();
-- (DOM::DocumentImpl::ParseMode)parseMode { return parseMode; }
+ doc->view()->ref();
-- (void)setPausedActions: (QMap<int, KJS::ScheduledAction*> *)pa
-{
- pausedActions = pa;
+ return self;
}
-- (QMap<int, KJS::ScheduledAction*> *)pausedActions
+- (DocumentImpl::ParseMode)parseMode
{
- return pausedActions;
+ return parseMode;
}
-- (void)_cleanupPausedActions
+- (PausedTimeouts *)pausedTimeouts
{
- if (pausedActions){
- QMapIterator<int,KJS::ScheduledAction*> it;
- for (it = pausedActions->begin(); it != pausedActions->end(); ++it) {
- KJS::ScheduledAction *action = *it;
- delete action;
- }
- delete pausedActions;
- pausedActions = 0;
- }
- QObject::clearPausedTimers(self);
+ return pausedTimeouts;
}
- (void)clear
{
- document = 0;
+ if (mousePressNode)
+ mousePressNode->deref();
mousePressNode = 0;
delete URL;
@@ -110,7 +95,8 @@
delete interpreterBuiltins;
interpreterBuiltins = 0;
- [self _cleanupPausedActions];
+ delete pausedTimeouts;
+ pausedTimeouts = 0;
}
- (void)invalidate
@@ -120,19 +106,22 @@
ASSERT(document->view());
ASSERT(!document->inPageCache());
- if (document && document->view()) {
- document->view()->deref();
+ if (document) {
+ KHTMLView *view = document->view();
+ if (view)
+ view->deref();
document->deref();
+ document = 0;
}
-
+
[self clear];
}
- (void)dealloc
{
if (document) {
- ASSERT(document->inPageCache());
ASSERT(document->view());
+ ASSERT(document->inPageCache());
KHTMLView *view = document->view();
@@ -145,10 +134,7 @@
document->removeAllEventListenersFromAllNodes();
}
document->deref();
-
- if (mousePressNode) {
- mousePressNode->deref();
- }
+ document = 0;
if (view) {
view->clearPart();
@@ -181,6 +167,7 @@
document->removeAllEventListenersFromAllNodes();
}
document->deref();
+ document = 0;
if (view) {
view->clearPart();
@@ -198,7 +185,7 @@
return document;
}
-- (DOM::NodeImpl *)mousePressNode
+- (NodeImpl *)mousePressNode
{
return mousePressNode;
}
1.13 +10 -15 WebCore/kwq/KWQTimer.h
Index: KWQTimer.h
===================================================================
RCS file: /cvs/root/WebCore/kwq/KWQTimer.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- KWQTimer.h 19 Sep 2005 18:52:13 -0000 1.12
+++ KWQTimer.h 7 Nov 2005 20:52:11 -0000 1.13
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2003, 2005 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,39 +27,34 @@
#define QTIMER_H_
#include "KWQObject.h"
-#include "KWQSignal.h"
-
-#ifdef __OBJC__
- at class NSTimer;
-#else
-class NSTimer;
-#endif
class QTimer : public QObject {
public:
- QTimer(QObject *parent = 0);
+ QTimer() : m_runLoopTimer(0), m_monitorFunction(0), m_timeoutSignal(this, SIGNAL(timeout())) { }
~QTimer() { stop(); }
- bool isActive() const;
+ bool isActive() const { return m_runLoopTimer; }
void start(int msec, bool singleShot = false);
void stop();
void fire();
static void singleShot(int msec, QObject *receiver, const char *member);
-
- static void immediateSingleShotOnMainThread(void (*func)());
// This is just a hack used by KWQKHTMLPart. The monitor function
// gets called when the timer starts and when it is stopped before firing,
// but not when the timer fires.
void setMonitor(void (*monitorFunction)(void *context), void *context);
- NSTimer *getNSTimer() { return m_timer; }
-private:
- NSTimer *m_timer;
+ CFAbsoluteTime fireDate() const { return CFRunLoopTimerGetNextFireDate(m_runLoopTimer); }
+
+private:
+ CFRunLoopTimerRef m_runLoopTimer;
void (*m_monitorFunction)(void *context);
void *m_monitorFunctionContext;
KWQSignal m_timeoutSignal;
+
+ QTimer(const QTimer&);
+ QTimer& operator=(const QTimer&);
};
#endif
1.20 +30 -125 WebCore/kwq/KWQTimer.mm
Index: KWQTimer.mm
===================================================================
RCS file: /cvs/root/WebCore/kwq/KWQTimer.mm,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- KWQTimer.mm 3 Oct 2005 21:13:10 -0000 1.19
+++ KWQTimer.mm 7 Nov 2005 20:52:11 -0000 1.20
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2003, 2005 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,111 +27,37 @@
#import "KWQTimer.h"
#import <kxmlcore/Assertions.h>
-#import "KWQLogging.h"
-#import "KWQFoundationExtras.h"
-// We know the Cocoa calls in this file are safe because they are all
-// to the simple ObjC class defined here, or simple NSTimer calls that
-// can't throw.
-
- at interface KWQTimerTarget : NSObject
-{
- QTimer *timer;
-}
-+ (KWQTimerTarget *)targetWithQTimer:(QTimer *)timer;
-- (void)timerFired:(id)userInfo;
- at end
-
- at interface KWQSingleShotTimerTarget : NSObject
-{
- KWQSlot *slot;
-}
-+ (KWQSingleShotTimerTarget *)targetWithQObject:(QObject *)object member:(const char *)member;
-- (void)timerFired:(id)userInfo;
- at end
-
- at implementation KWQTimerTarget
-
-+ (KWQTimerTarget *)targetWithQTimer:(QTimer *)t
-{
- KWQTimerTarget *target = [[[self alloc] init] autorelease];
- target->timer = t;
- return target;
-}
-
-- (void)timerFired:(id)userInfo
-{
- timer->fire();
-}
-
- at end
-
- at implementation KWQSingleShotTimerTarget
-
-+ (KWQSingleShotTimerTarget *)targetWithQObject:(QObject *)object member:(const char *)member
-{
- KWQSingleShotTimerTarget *target = [[[self alloc] init] autorelease];
- target->slot = new KWQSlot(object, member);
- return target;
-}
-
-- (void)dealloc
-{
- delete slot;
- [super dealloc];
-}
-
-- (void)finalize
-{
- delete slot;
- [super finalize];
-}
-
-- (void)timerFired:(id)userInfo
+static void timerFired(CFRunLoopTimerRef, void *info)
{
- slot->call();
-}
-
- at end
-
-QTimer::QTimer(QObject *parent)
- : m_timer(nil), m_monitorFunction(0), m_timeoutSignal(this, SIGNAL(timeout()))
-{
- if (parent) LOG(NotYetImplemented, "Parent pointer ignored. QTimer will be leaked and may fire after parent dealloc causing crash.");
-}
-
-bool QTimer::isActive() const
-{
- return m_timer;
+ ((QTimer *)info)->fire();
}
void QTimer::start(int msec, bool singleShot)
{
stop();
- m_timer = KWQRetain([NSTimer scheduledTimerWithTimeInterval:(msec / 1000.0)
- target:[KWQTimerTarget targetWithQTimer:this]
- selector:@selector(timerFired:)
- userInfo:nil
- repeats:!singleShot]);
- if (m_monitorFunction) {
+ CFTimeInterval interval = msec * 0.001;
+ CFRunLoopTimerContext context = { 0, this, 0, 0, 0 };
+ m_runLoopTimer = CFRunLoopTimerCreate(0, CFAbsoluteTimeGetCurrent() + interval,
+ singleShot ? 0 : interval, 0, 0, timerFired, &context);
+ CFRunLoopAddTimer(CFRunLoopGetCurrent(), m_runLoopTimer, kCFRunLoopDefaultMode);
+
+ if (m_monitorFunction)
m_monitorFunction(m_monitorFunctionContext);
- }
}
void QTimer::stop()
{
- if (m_timer == nil) {
+ if (!m_runLoopTimer)
return;
- }
- [m_timer invalidate];
- KWQRelease(m_timer);
- m_timer = nil;
+ CFRunLoopTimerInvalidate(m_runLoopTimer);
+ CFRelease(m_runLoopTimer);
+ m_runLoopTimer = 0;
- if (m_monitorFunction) {
+ if (m_monitorFunction)
m_monitorFunction(m_monitorFunctionContext);
- }
}
void QTimer::setMonitor(void (*monitorFunction)(void *context), void *context)
@@ -143,52 +69,31 @@
void QTimer::fire()
{
- // Ensure that m_timer is kept around for duration of callback.
- // Final reference will eventually be released in stop(), which may be called
- // in this frame, hence the need to ensure the timer is kept around until
- // the pool is released.
- [[m_timer retain] autorelease];
+ if (m_runLoopTimer && !CFRunLoopTimerIsValid(m_runLoopTimer)) {
+ CFRunLoopTimerInvalidate(m_runLoopTimer);
+ CFRelease(m_runLoopTimer);
+ m_runLoopTimer = 0;
+ }
// Note: This call may destroy the QTimer, so be sure not to touch any fields afterward.
m_timeoutSignal.call();
}
-void QTimer::singleShot(int msec, QObject *receiver, const char *member)
-{
- [NSTimer scheduledTimerWithTimeInterval:(msec / 1000.0)
- target:[KWQSingleShotTimerTarget targetWithQObject:receiver member:member]
- selector:@selector(timerFired:)
- userInfo:nil
- repeats:NO];
-}
-
- at interface KWQMainThreadPerformTarget : NSObject
-{
- void (*_func)();
-}
-
-- (id)initWithFunction:(void (*)())func;
-- (void)callFunction:(id)ignore;
- at end
-
- at implementation KWQMainThreadPerformTarget
-- (id)initWithFunction:(void (*)())func
+static void deleteKWQSlot(const void *info)
{
- if ((self = [super init])) {
- _func = func;
- }
- return self;
+ delete (KWQSlot *)info;
}
-- (void)callFunction:(id)ignore
+static void singleShotTimerFired(CFRunLoopTimerRef, void *info)
{
- _func();
+ ((KWQSlot *)info)->call();
}
- at end
-
-void QTimer::immediateSingleShotOnMainThread(void (*func)())
+void QTimer::singleShot(int msec, QObject *receiver, const char *member)
{
- [[[KWQMainThreadPerformTarget alloc] initWithFunction:func] performSelectorOnMainThread:@selector(callFunction) withObject:nil waitUntilDone:NO];
+ CFRunLoopTimerContext context = { 0, new KWQSlot(receiver, member), 0, deleteKWQSlot, 0 };
+ CFRunLoopTimerRef timer = CFRunLoopTimerCreate(0, CFAbsoluteTimeGetCurrent() + msec * 0.001,
+ 0, 0, 0, singleShotTimerFired, &context);
+ CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode);
+ CFRelease(timer);
}
-
1.425 +14 -12 WebCore/kwq/WebCoreBridge.mm
Index: WebCoreBridge.mm
===================================================================
RCS file: /cvs/root/WebCore/kwq/WebCoreBridge.mm,v
retrieving revision 1.424
retrieving revision 1.425
diff -u -r1.424 -r1.425
--- WebCoreBridge.mm 3 Nov 2005 19:12:07 -0000 1.424
+++ WebCoreBridge.mm 7 Nov 2005 20:52:11 -0000 1.425
@@ -476,13 +476,11 @@
- (BOOL)saveDocumentToPageCache
{
DocumentImpl *doc = _part->xmlDocImpl();
- if (!doc) {
+ if (!doc)
return NO;
- }
-
- if (!doc->view()) {
+ if (!doc->view())
return NO;
- }
+
_part->clearTimers();
InterpreterLock lock;
@@ -496,14 +494,18 @@
SavedBuiltins *interpreterBuiltins = new SavedBuiltins;
_part->saveInterpreterBuiltins(*interpreterBuiltins);
- KWQPageState *pageState = [[[KWQPageState alloc] initWithDocument:doc
- URL:_part->m_url
- windowProperties:windowProperties
- locationProperties:locationProperties
- interpreterBuiltins:interpreterBuiltins] autorelease];
- [pageState setPausedActions: _part->pauseActions((const void *)pageState)];
+ KWQPageState *pageState = [[KWQPageState alloc] initWithDocument:doc
+ URL:_part->m_url
+ windowProperties:windowProperties
+ locationProperties:locationProperties
+ interpreterBuiltins:interpreterBuiltins
+ pausedTimeouts:_part->pauseTimeouts()];
+
+ BOOL result = [self saveDocumentToPageCache:pageState];
+
+ [pageState release];
- return [self saveDocumentToPageCache:pageState];
+ return result;
}
- (BOOL)canCachePage
More information about the webkit-changes
mailing list