mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-31 22:25:30 +00:00
207 lines
8.2 KiB
C++
207 lines
8.2 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
* Reserved.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
//========================================================================================
|
|
// This file contains a suite of classes that allow posting and deferred execution
|
|
// of tasks in any powerplant application (except for CDeferredCloseTask, which is
|
|
// specific to Communicator).
|
|
|
|
// CDeferredTaskManager: A singleton class, manages each per-window queue of tasks,
|
|
// together with one global "nil" queue. It is created only when
|
|
// a task is first posted, and is deleted as soon as no more
|
|
// tasks exist.
|
|
// CDeferredTaskQueue: A queue of tasks. Each task belongs to a window (except that
|
|
// one global "nil" queue is allowed), and tasks for
|
|
// different windows are in different queues. A queue is created
|
|
// only when needed and is deleted immediately it becomes empty.
|
|
|
|
// CDeferredTask: The abstract base class for tasks that can be posted.
|
|
// CDeferredCommand This is an example of a deferred task object. Its ExecuteSelf()
|
|
// method calls ObeyCommand
|
|
// CDeferredMessage This is another example, but calls ListenToMessage instead.
|
|
// CDeferredCloseTask Another example. Closes a window when it's safe.
|
|
//========================================================================================
|
|
|
|
#include <LPeriodical.h>
|
|
|
|
class CDeferredTaskQueue; // forward.
|
|
class CDeferredTask; // forward.
|
|
|
|
//========================================================================================
|
|
class CDeferredTaskManager
|
|
// On each idle, the task manager will walk the queue list. For each queue, it will
|
|
// take the following action:
|
|
// Tell the first task to execute. If the task returns true, the task is then
|
|
// deleted. If it returns false, it is left in the queue to be tried on the next idle.
|
|
// There are only a few public entry points: Post and Remove. Each of these has
|
|
// an LPane* parameter that is used to work out which window, and hence which queue, the
|
|
// task belongs to. When posting, a new queue will be opened for the window in question,
|
|
// if none exists. When removing, the queue is deleted if no more tasks remain in it.
|
|
//========================================================================================
|
|
: public LPeriodical
|
|
{
|
|
public: // ---------- BEGIN PUBLIC API ------------- //
|
|
static void Post(CDeferredTask* inTask, LPane* inPane,
|
|
bool inUnique = false);
|
|
// Post a task to the end of the queue. If
|
|
// inUnique is true all others of the same
|
|
// type will be removed.
|
|
static void Remove(CDeferredTask*& inTask, LPane* inPane);
|
|
// Remove task.
|
|
static void ClearQueue(LPane* inPane);
|
|
// Remove all tasks from this queue.
|
|
static void DoQuit(Int32 inSaveOption);
|
|
// Finish all the close tasks.
|
|
// ---------- END PUBLIC API ------------- //
|
|
protected:
|
|
CDeferredTaskManager();
|
|
~CDeferredTaskManager();
|
|
virtual void SpendTime(const EventRecord&);
|
|
void DoExecuteTasks();
|
|
void DoPost(
|
|
CDeferredTask* inTask,
|
|
LPane* inPane,
|
|
Boolean inUnique);
|
|
void DoRemove(
|
|
CDeferredTask*& inTask,
|
|
LPane* inPane);
|
|
void DoRemove(
|
|
CDeferredTask*& inTask,
|
|
LWindow* inWindow);
|
|
void DoClearQueue(LPane* inPane);
|
|
void DoClearQueue(LWindow* inWindow);
|
|
void RemoveNextQueueAfter(
|
|
CDeferredTaskQueue* inPreviousQueue);
|
|
// data
|
|
protected:
|
|
CDeferredTaskQueue* mQueueList;
|
|
static CDeferredTaskManager* sManager;
|
|
}; // class CDeferredTaskManager
|
|
|
|
//========================================================================================
|
|
class CDeferredTaskQueue
|
|
// There is one queue per window, and optionally one global one (with mQueueWindow
|
|
// == nil). The first task in each queue "blocks" any subsequent tasks in the same queue.
|
|
// FIFO order is thus guaranteed.
|
|
//========================================================================================
|
|
{
|
|
friend class CDeferredTaskManager;
|
|
protected:
|
|
CDeferredTaskQueue(LWindow* inWindow);
|
|
~CDeferredTaskQueue();
|
|
void DoPost(CDeferredTask* inTask);
|
|
void DoRemove(CDeferredTask*& inTask);
|
|
void DoRemoveType(CDeferredTask* inTask);
|
|
void DoClearSelf();
|
|
// data
|
|
protected:
|
|
LWindow* mQueueWindow;
|
|
CDeferredTaskQueue* mNext;
|
|
CDeferredTask* mFrontTask;
|
|
}; // class CDeferredWindowTaskQueue
|
|
|
|
//========================================================================================
|
|
class CDeferredTask
|
|
// Base class for various useful types of deferred tasks. Derived classes must implement
|
|
// ExecuteSelf(), returning an ExecuteResult value of:
|
|
// eWaitStayFront task is to be tried again, and wishes to remain blocking the queue
|
|
// eWaitDoneDelete task has done its work and is to be deleted
|
|
// eWaitStepBack task is to be tried again, but willing to step back in the queue
|
|
// to give the next task a chance. (background, low priority)
|
|
//========================================================================================
|
|
{
|
|
protected:
|
|
enum ExecuteResult { eWaitStayFront, eDoneDelete, eWaitStepBack };
|
|
CDeferredTask();
|
|
virtual ~CDeferredTask();
|
|
virtual ExecuteResult ExecuteSelf() = 0;
|
|
private:
|
|
ExecuteResult Execute();
|
|
// data
|
|
protected:
|
|
friend class CDeferredTaskManager;
|
|
friend class CDeferredTaskQueue;
|
|
CDeferredTask* mNext;
|
|
Boolean mExecuting; // reentrancy protection.
|
|
#if DEBUG
|
|
UInt32 mExecuteAttemptCount;
|
|
#endif
|
|
}; // class CDeferredTask
|
|
|
|
class LCommander;
|
|
|
|
//========================================================================================
|
|
class CDeferredCommand
|
|
// This is an example of a CDeferredTask. This one calls ObeyCommand on a commander.
|
|
//========================================================================================
|
|
: public CDeferredTask
|
|
{
|
|
public:
|
|
CDeferredCommand(
|
|
LCommander* inCommander,
|
|
CommandT inCommand,
|
|
void* ioParam);
|
|
virtual ExecuteResult ExecuteSelf();
|
|
// data
|
|
LCommander* mCommander;
|
|
CommandT mCommand;
|
|
void* mParam;
|
|
}; // class CDeferredCommand
|
|
|
|
class LListener;
|
|
|
|
//========================================================================================
|
|
class CDeferredMessage
|
|
// This is an example of a CDeferredTask. This one calls ListenToMessage on a listener.
|
|
//========================================================================================
|
|
: public CDeferredTask
|
|
{
|
|
public:
|
|
CDeferredMessage(
|
|
LListener* inListener,
|
|
MessageT inMessage,
|
|
void* ioParam);
|
|
virtual ExecuteResult ExecuteSelf();
|
|
// data
|
|
LListener* mListener;
|
|
MessageT mMessage;
|
|
void* mParam;
|
|
}; // class CDeferredMessage
|
|
|
|
class CNetscapeWindow;
|
|
|
|
//========================================================================================
|
|
class CDeferredCloseTask
|
|
// This guy closes a window at a later, safer time. The parameter to the constructor is
|
|
// any pane (usually the calling pane), from which the window object is deduced. This
|
|
// only works for CNetscapeWindows
|
|
//========================================================================================
|
|
: public CDeferredTask
|
|
{
|
|
public:
|
|
CDeferredCloseTask(LPane* inPane);
|
|
static CDeferredCloseTask* DeferredClose(LPane* inPane);
|
|
protected:
|
|
virtual ExecuteResult ExecuteSelf();
|
|
// data
|
|
protected:
|
|
CNetscapeWindow* mWindow;
|
|
}; // class CDeferredCloseTask
|