Added client methods for adding or updating multiple table rows from a single parameter list.

Added method to postpone processing of message copies to the UI thread.


git-svn-id: http://yate.null.ro/svn/yate/trunk@2242 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2008-09-29 08:22:20 +00:00
parent b2dae7cb22
commit 3f42f160c2
2 changed files with 118 additions and 0 deletions

View File

@ -47,6 +47,7 @@ public:
delOption,
getOptions,
addTableRow,
setMultipleRows,
insertTableRow,
delTableRow,
setTableRow,
@ -100,6 +101,19 @@ private:
void** m_pointer;
};
// holder for a postponed message
class PostponedMessage : public Message
{
public:
inline PostponedMessage(const Message& msg, int id)
: Message(msg), m_id(id)
{ }
inline int id() const
{ return m_id; }
private:
int m_id;
};
// engine.start message handler used to notify logics
class EngineStartHandler : public MessageHandler
{
@ -132,6 +146,8 @@ static String s_hangupReason = "User hangup";
static unsigned int s_eventLen = 0; // Log maximum lines (0: unlimited)
static Mutex s_debugMutex;
static Mutex s_proxyMutex;
static Mutex s_postponeMutex;
static ObjList s_postponed;
static NamedList* s_debugLog = 0;
static ClientThreadProxy* s_proxy = 0;
static bool s_busy = false;
@ -391,6 +407,14 @@ bool Window::addTableRow(const String& name, const String& item, const NamedList
return false;
}
// stub function for setting multiple lines at once
bool Window::setMultipleRows(const String& name, const NamedList& data, const String& prefix)
{
DDebug(ClientDriver::self(),DebugInfo,"stub setMultipleRows('%s',%p,'%s') [%p]",
name.c_str(),&data,data,prefix.c_str(),this);
return false;
}
// stub function for inserting a row to a table
bool Window::insertTableRow(const String& name, const String& item,
const String& before, const NamedList* data)
@ -637,6 +661,9 @@ void ClientThreadProxy::process()
case addTableRow:
m_rval = client->addTableRow(m_name,m_item,m_params,m_bool,m_wnd,m_skip);
break;
case setMultipleRows:
m_rval = client->setMultipleRows(m_name,*m_params,m_item,m_wnd,m_skip);
break;
case insertTableRow:
m_rval = client->insertTableRow(m_name,m_item,m_text,m_params,m_wnd,m_skip);
break;
@ -1327,6 +1354,25 @@ bool Client::addTableRow(const String& name, const String& item, const NamedList
return ok;
}
bool Client::setMultipleRows(const String& name, const NamedList& data, const String& prefix, Window* wnd, Window* skip)
{
if (needProxy()) {
ClientThreadProxy proxy(ClientThreadProxy::setMultipleRows,name,prefix,false,&data,wnd,skip);
return proxy.execute();
}
if (wnd)
return wnd->setMultipleRows(name,data,prefix);
++s_changing;
bool ok = false;
for (ObjList* o = m_windows.skipNull(); o; o = o->skipNext()) {
wnd = static_cast<Window*>(o->get());
if (wnd != skip)
ok = wnd->setMultipleRows(name,data,prefix) || ok;
}
--s_changing;
return ok;
}
// Function to insert a new row into a table with the "name" id
bool Client::insertTableRow(const String& name, const String& item,
const String& before, const NamedList* data, Window* wnd, Window* skip)
@ -1713,6 +1759,18 @@ bool Client::received(Message& msg, int id)
return processed;
}
// Postpone messages to be redispatched from UI thread
bool Client::postpone(const Message& msg, int id)
{
if (isCurrent())
return false;
PostponedMessage* postponed = new PostponedMessage(msg,id);
s_postponeMutex.lock();
s_postponed.append(postponed);
s_postponeMutex.unlock();
return true;
}
// Handle actions from user interface
bool Client::action(Window* wnd, const String& name, NamedList* params)
{
@ -1840,6 +1898,31 @@ void Client::idleActions()
for (ObjList* o = s_logics.skipNull(); o; o = o->skipNext())
(static_cast<ClientLogic*>(o->get()))->idleTimerTick(time);
}
// Dispatch postponed messages
ObjList postponed;
int postponedCount = 0;
s_postponeMutex.lock();
for (;;) {
// First move some messages from the global list to the local one
GenObject* msg = s_postponed.remove(false);
if (!msg)
break;
postponed.append(msg);
// arbitrary limit to avoid freezing the user interface
if (++postponedCount >= 16)
break;
}
s_postponeMutex.unlock();
if (postponedCount) {
Debug(ClientDriver::self(),DebugInfo,"Dispatching %d postponed messages",postponedCount);
for (;;) {
PostponedMessage* msg = static_cast<PostponedMessage*>(postponed.remove(false));
if (!msg)
break;
received(*msg,msg->id());
delete msg;
}
}
// arbitrary limit to let other threads run too
for (int i = 0; i < 4; i++) {
if (!s_busy)

View File

@ -224,6 +224,15 @@ public:
virtual bool addTableRow(const String& name, const String& item,
const NamedList* data = 0, bool atStart = false);
/**
* Append or update several table rows at once
* @param name Name of the element
* @param data Parameters to initialize the rows with
* @param prefix Prefix to match (and remove) in parameter names
* @return True if all the operations were successfull
*/
virtual bool setMultipleRows(const String& name, const NamedList& data, const String& prefix = String::empty());
/**
* Insert a row into a table owned by this window
* @param name Name of the element
@ -530,6 +539,14 @@ public:
bool atStart = false)
{ return false; }
/** Append or update several table rows at once
* @param data Parameters to initialize the rows with
* @param prefix Prefix to match (and remove) in parameter names
* @return True if all the operations were successfull
*/
virtual bool setMultipleRows(const NamedList& data, const String& prefix = String::empty())
{ return false; }
/**
* Insert a row into a table
* @param item Name of the item to insert
@ -916,6 +933,16 @@ public:
bool addTableRow(const String& name, const String& item, const NamedList* data = 0,
bool atStart = false, Window* wnd = 0, Window* skip = 0);
/** Append or update several table rows at once
* @param name Name of the element
* @param data Parameters to initialize the rows with
* @param prefix Prefix to match (and remove) in parameter names
* @param wnd Optional window owning the element
* @param skip Optional window to skip if wnd is 0
* @return True if all the operations were successfull
*/
bool setMultipleRows(const String& name, const NamedList& data, const String& prefix = String::empty(), Window* wnd = 0, Window* skip = 0);
/**
* Insert a row into a table owned by this window
* @param name Name of the element
@ -1020,6 +1047,14 @@ public:
static ObjList* listWindows();
void idleActions();
/**
* Postpone a copy of a message to be dispatched from the UI thread
* @param msg Message to be postponed
* @param id Identifier of the message to be used on dispatch
* @return True if the UI thread was not current so the message was postponed
*/
bool postpone(const Message& msg, int id);
/**
* Show a file open dialog window
* This method isn't using the proxy thread since it's usually called on UI action