[rkward-cvs] SF.net SVN: rkward:[2746] trunk/rkward/rkward/plugin
tfry at users.sourceforge.net
tfry at users.sourceforge.net
Fri Feb 19 18:27:38 UTC 2010
Revision: 2746
http://rkward.svn.sourceforge.net/rkward/?rev=2746&view=rev
Author: tfry
Date: 2010-02-19 18:27:37 +0000 (Fri, 19 Feb 2010)
Log Message:
-----------
Move auto-submission code outside of RKStandardComponent. This should put an end to the crashes during automated testing.
Modified Paths:
--------------
trunk/rkward/rkward/plugin/rkcomponent.cpp
trunk/rkward/rkward/plugin/rkcomponent.h
trunk/rkward/rkward/plugin/rkcomponentmap.cpp
trunk/rkward/rkward/plugin/rkstandardcomponent.cpp
trunk/rkward/rkward/plugin/rkstandardcomponent.h
Modified: trunk/rkward/rkward/plugin/rkcomponent.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponent.cpp 2010-02-18 21:55:31 UTC (rev 2745)
+++ trunk/rkward/rkward/plugin/rkcomponent.cpp 2010-02-19 18:27:37 UTC (rev 2746)
@@ -2,7 +2,7 @@
rkcomponent - description
-------------------
begin : Tue Dec 13 2005
- copyright : (C) 2005, 2006, 2009 by Thomas Friedrichsmeier
+ copyright : (C) 2005, 2006, 2009, 2010 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -152,6 +152,22 @@
return false; // never happens in RKComponentBase, but might in subclasses
}
+RKComponentBase::ComponentStatus RKComponentBase::recursiveStatus () {
+ RK_TRACE (PLUGIN);
+
+ bool processing = false;
+ bool children_satisfied = true;
+ for (QHash<QString, RKComponentBase*>::const_iterator it = child_map.constBegin (); it != child_map.constEnd (); ++it) {
+ ComponentStatus s = it.value ()->recursiveStatus ();
+ if (s == Dead) return Dead;
+ if (s == Processing) processing = true;
+ else if (s != Satisfied) children_satisfied = false;
+ }
+ if (processing) return Processing;
+ if (children_satisfied && isSatisfied ()) return Satisfied;
+ return Unsatisfied;
+}
+
//############### RKComponent ########################
RKComponent::RKComponent (RKComponent *parent_component, QWidget *parent_widget) : QWidget (parent_widget) {
@@ -227,6 +243,7 @@
bool RKComponent::isValid () {
RK_TRACE (PLUGIN);
+#warning TODO: I do not think we need this. Use recursiveStatus, instead
for (QHash<QString, RKComponentBase*>::const_iterator it = child_map.constBegin (); it != child_map.constEnd (); ++it) {
if (!(it.value ()->isSatisfied ())) return false;
Modified: trunk/rkward/rkward/plugin/rkcomponent.h
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponent.h 2010-02-18 21:55:31 UTC (rev 2745)
+++ trunk/rkward/rkward/plugin/rkcomponent.h 2010-02-19 18:27:37 UTC (rev 2746)
@@ -2,7 +2,7 @@
rkcomponent - description
-------------------
begin : Tue Dec 13 2005
- copyright : (C) 2005, 2006, 2007, 2009 by Thomas Friedrichsmeier
+ copyright : (C) 2005, 2006, 2007, 2009, 2010 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -67,6 +67,12 @@
NotAllSettingsApplied,
NoSuchComponent
};
+ enum ComponentStatus {
+ Dead,
+ Processing,
+ Unsatisfied,
+ Satisfied
+ };
/** for RTTI. see RKComponentBase::RKComponentTypes */
virtual int type () = 0;
/** tries to locate a component (or property) described by identifier as a child (of any generation) of this RKComponentBase. If found, a pointer to this is returned. Also, the modifier parameter is set to hold any remaining modifier contained in the identifier.
@@ -83,6 +89,8 @@
bool isComponent () { return (type () >= ComponentBase); };
/** returns satisfaction state. see setRequired () */
virtual bool isSatisfied ();
+/** returns somewhat more elaborate state than isSatisfied(). (Effectively identical in the base class). */
+ virtual ComponentStatus recursiveStatus ();
/** currently valid (i.e. satisfied, even if required)? default implementation always returns true */
virtual bool isValid () { return true; };
/** set to required: will only be satisfied if it is valid. Else: always satisfied (but subclasses might override to always be dissatisfied on really bad values. By default RKComponentBase is required at construction */
Modified: trunk/rkward/rkward/plugin/rkcomponentmap.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentmap.cpp 2010-02-18 21:55:31 UTC (rev 2745)
+++ trunk/rkward/rkward/plugin/rkcomponentmap.cpp 2010-02-19 18:27:37 UTC (rev 2746)
@@ -2,7 +2,7 @@
rkcomponentmap.cpp - description
-------------------
begin : Thu May 12 2005
- copyright : (C) 2005, 2006, 2007, 2009 by Thomas Friedrichsmeier
+ copyright : (C) 2005, 2006, 2007, 2009, 2010 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -19,6 +19,8 @@
#include <qfileinfo.h>
#include <qdir.h>
+#include <QTime>
+#include <QObjectCleanupHandler>
#include <klocale.h>
#include <kactioncollection.h>
@@ -265,27 +267,45 @@
// not considered an error
}
+ if (submit_mode == ManualSubmit) return true;
+
+
// Auto-Submit
- if (submit_mode != ManualSubmit) {
+ // the call to processEvents(), below, is quite dangerous, as the component self-destructs on errors. This helps us prevent crashes.
+ QObjectCleanupHandler chandler;
+ chandler.add (component);
+
#ifndef Q_OS_WIN
- // if the plugin takes longer than 5 seconds to settle, than that really is sort of buggy...
- bool submit_ok = component->submit (5000, in_chain);
+ // if the plugin takes longer than 5 seconds to settle, than that really is sort of buggy...
+ const int max_wait = 5000;
#else
#warning Temporary workaround. Remove this.
- // (yet on windows, the PHP backend is *real* slow. We give it a bit longer as long as we still use it...
- bool submit_ok = component->submit (50000, in_chain);
+ // (yet on windows, the PHP backend is *real* slow. We give it a bit longer as long as we still use it...
+ const int max_wait = 50000;
#endif
- if (!submit_ok) {
- if (submit_mode == AutoSubmitOrFail) {
- component->kill ();
- }
- _message.append (i18n ("\nThe plugin could not be auto-submitted with these settings."));
- if (message) *message = _message;
- else KMessageBox::sorry (RKWardMainWindow::getMain (), _message, i18n ("Could not submit"));
+ QTime t;
+ t.start ();
+ while ((!chandler.isEmpty ()) && (component->recursiveStatus () == RKComponentBase::Processing) && (t.elapsed () < max_wait)) {
+ QCoreApplication::processEvents (QEventLoop::ExcludeUserInputEvents, (max_wait / 2));
+ }
+ RKComponentBase::ComponentStatus status = RKComponentBase::Dead;
+ if (!chandler.isEmpty ()) status = component->recursiveStatus ();
+ chandler.remove (component); // otherwise it would auto-delete the component, later!
- return (submit_mode != AutoSubmitOrFail);
+ if (status == RKComponentBase::Satisfied) {
+ bool ok = component->submit (in_chain);
+ RK_ASSERT (ok);
+ } else {
+ if (submit_mode == AutoSubmitOrFail) {
+ if (status != RKComponentBase::Dead) component->kill ();
}
+
+ _message.append (i18n ("\nThe plugin could not be auto-submitted with these settings."));
+ if (message) *message = _message;
+ else KMessageBox::sorry (RKWardMainWindow::getMain (), _message, i18n ("Could not submit"));
+
+ return (submit_mode != AutoSubmitOrFail);
}
return true;
Modified: trunk/rkward/rkward/plugin/rkstandardcomponent.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkstandardcomponent.cpp 2010-02-18 21:55:31 UTC (rev 2745)
+++ trunk/rkward/rkward/plugin/rkstandardcomponent.cpp 2010-02-19 18:27:37 UTC (rev 2746)
@@ -2,7 +2,7 @@
rkstandardcomponent - description
-------------------
begin : Sun Feb 19 2006
- copyright : (C) 2006, 2007, 2009 by Thomas Friedrichsmeier
+ copyright : (C) 2006, 2007, 2009, 2010 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -24,8 +24,6 @@
#include <qtimer.h>
#include <QVBoxLayout>
#include <QGroupBox>
-#include <QTime>
-#include <QObjectCleanupHandler>
#include <klocale.h>
#include <kmessagebox.h>
@@ -110,9 +108,7 @@
QString dummy = QFileInfo (filename).path() + '/' + xml->getStringAttribute (element, "file", "::nosuchfile::", DL_INFO);
have_help = QFileInfo (dummy).exists ();
- handle_change_timer = new QTimer (this);
- handle_change_timer->setSingleShot (true);
- connect (handle_change_timer, SIGNAL (timeout ()), this, SLOT (handleChange ()));
+ update_pending = false;
// construct the GUI
if (!parent_component) { // top-level
@@ -326,34 +322,24 @@
changed ();
}
-bool RKStandardComponent::submit (int max_wait, RCommandChain *in_chain) {
+RKComponentBase::ComponentStatus RKStandardComponent::recursiveStatus () {
RK_TRACE (PLUGIN);
- // the call to processEvents(), below, is quite dangerous, as the component self-destructs on errors. This helps us prevent crashes.
- QObjectCleanupHandler chandler;
- chandler.add (this);
+ if (killed) return Dead;
+ if (backend->isBusy () || update_pending) return Processing;
+ return (RKComponentBase::recursiveStatus ());
+}
- RCommandChain *old_chain = command_chain; // should always be 0, but let's store it cleanly
- command_chain = in_chain;
- bool result = false;
+bool RKStandardComponent::submit (RCommandChain *in_chain) {
+ RK_TRACE (PLUGIN);
- QTime t;
- t.start ();
- while ((handle_change_timer->isActive () || backend->isBusy ()) && (t.elapsed () < max_wait)) {
- if (chandler.isEmpty () || killed) return (false);
- QCoreApplication::processEvents (QEventLoop::ExcludeUserInputEvents, (max_wait / 2));
- if (chandler.isEmpty () || killed) return (false);
- }
- if (!(handle_change_timer->isActive () || backend->isBusy ())) {
- if (isSatisfied ()) {
- gui->ok ();
- result = true;
- }
- }
- if (chandler.isEmpty () || killed) return (result);
- command_chain = old_chain;
- chandler.remove (this);
- return result;
+ if (!isSatisfied ()) return false;
+
+ RCommandChain *prev_chain = command_chain;
+ command_chain = in_chain;
+ gui->ok ();
+ command_chain = prev_chain;
+ return true;
}
void RKStandardComponent::close () {
@@ -372,13 +358,18 @@
if (!created) return;
if (gui) gui->enableSubmit (false);
- // delay actual handling, until all changes have run up
- handle_change_timer->start (10);
+ // don't trigger update twice
+ if (!update_pending) {
+ update_pending = true;
+ QTimer::singleShot (0, this, SLOT (handleChange ()));
+ }
}
void RKStandardComponent::handleChange () {
RK_TRACE (PLUGIN);
+ if (killed) return;
+ update_pending = false;
backend->preprocess (0);
backend->calculate (0);
backend->printout (0);
Modified: trunk/rkward/rkward/plugin/rkstandardcomponent.h
===================================================================
--- trunk/rkward/rkward/plugin/rkstandardcomponent.h 2010-02-18 21:55:31 UTC (rev 2745)
+++ trunk/rkward/rkward/plugin/rkstandardcomponent.h 2010-02-19 18:27:37 UTC (rev 2746)
@@ -2,7 +2,7 @@
rkstandardcomponent - description
-------------------
begin : Sun Feb 19 2006
- copyright : (C) 2006, 2007, 2009 by Thomas Friedrichsmeier
+ copyright : (C) 2006, 2007, 2009, 2010 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -69,13 +69,14 @@
QString getFilename () { return filename; };
RKComponentHandle *getHandle () { return handle; };
bool haveHelp () { return have_help; };
-/** tries to submit. Warning: This function waits for all changes to come in and may not return immediately!
- at param max_wait Maximum time to wait for changes to settle in msecs (approx.)
+/** Submits the current code (by simulating a click on the ok button).
@param in_chain The command chain to insert the command in (0 for regular command stack).
- at return true, if the plugin-code could be submitted */
- bool submit (int max_wait=1000, RCommandChain *in_chain = 0);
+ at return false, if the plugin-code could not be submitted (e.g. plugin was not satisfied) */
+ bool submit (RCommandChain *in_chain = 0);
/** convenience access function: closes the corresponding GUI */
void close ();
+/** reimplemented to actually return Dead or Processing when appropriate */
+ ComponentStatus recursiveStatus ();
RCommandChain *commandChain () const { return command_chain; };
public slots:
@@ -104,7 +105,7 @@
RKStandardComponentGUI *gui;
RKComponentHandle *handle;
RKStandardComponentStack *wizard;
- QTimer *handle_change_timer;
+ bool update_pending;
RCommandChain *command_chain;
/** Avoid updating code-display, etc. until the component is fully created */
bool created;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the rkward-tracker
mailing list