[rkward-cvs] SF.net SVN: rkward-code:[4552] trunk/rkward/rkward/core
tfry at users.sf.net
tfry at users.sf.net
Fri Feb 22 16:07:51 UTC 2013
Revision: 4552
http://sourceforge.net/p/rkward/code/4552
Author: tfry
Date: 2013-02-22 16:07:50 +0000 (Fri, 22 Feb 2013)
Log Message:
-----------
Use hashes, instead of class members for storing special child objects.
Modified Paths:
--------------
trunk/rkward/rkward/core/rcontainerobject.cpp
trunk/rkward/rkward/core/rcontainerobject.h
trunk/rkward/rkward/core/renvironmentobject.cpp
trunk/rkward/rkward/core/renvironmentobject.h
trunk/rkward/rkward/core/rkmodificationtracker.cpp
trunk/rkward/rkward/core/rkpseudoobjects.h
trunk/rkward/rkward/core/rkrownames.cpp
trunk/rkward/rkward/core/robject.cpp
trunk/rkward/rkward/core/robject.h
Modified: trunk/rkward/rkward/core/rcontainerobject.cpp
===================================================================
--- trunk/rkward/rkward/core/rcontainerobject.cpp 2013-02-22 10:18:58 UTC (rev 4551)
+++ trunk/rkward/rkward/core/rcontainerobject.cpp 2013-02-22 16:07:50 UTC (rev 4552)
@@ -2,7 +2,7 @@
rcontainerobject - description
-------------------
begin : Thu Aug 19 2004
- copyright : (C) 2004, 2006, 2007, 2009, 2010, 2011, 2012 by Thomas Friedrichsmeier
+ copyright : (C) 2004-2013 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -34,7 +34,6 @@
RContainerObject::RContainerObject (RObject *parent, const QString &name) : RObject (parent, name) {
RK_TRACE (OBJECTS);
type = Container;
- rownames_object = 0;
}
RContainerObject::~RContainerObject () {
@@ -44,7 +43,6 @@
for (int i = childmap.size () - 1; i >= 0; --i) {
delete childmap[i];
}
- delete rownames_object;
}
RObject *RContainerObject::updateChildStructure (RObject *child, RData *new_data, bool just_created) {
@@ -238,16 +236,18 @@
RKRowNames* RContainerObject::rowNames () {
RK_TRACE (OBJECTS);
- if (!rownames_object) {
- rownames_object = new RKRowNames (this);
+ if (!hasPseudoObject (RowNamesObject)) {
+ setSpecialChildObject (new RKRowNames (this), RowNamesObject);
updateRowNamesObject ();
}
- return rownames_object;
+ return rownames_objects.value (this);
}
void RContainerObject::updateRowNamesObject () {
RK_TRACE (OBJECTS);
+ RKRowNames *rownames_object = 0;
+ if (hasPseudoObject (RowNamesObject)) rownames_object = rownames_objects.value (this);
if (!rownames_object) return;
int childlen = 0;
Modified: trunk/rkward/rkward/core/rcontainerobject.h
===================================================================
--- trunk/rkward/rkward/core/rcontainerobject.h 2013-02-22 10:18:58 UTC (rev 4551)
+++ trunk/rkward/rkward/core/rcontainerobject.h 2013-02-22 16:07:50 UTC (rev 4552)
@@ -2,7 +2,7 @@
rcontainerobject - description
-------------------
begin : Thu Aug 19 2004
- copyright : (C) 2004, 2006, 2007, 2010, 2011 by Thomas Friedrichsmeier
+ copyright : (C) 2004-2013 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -76,7 +76,6 @@
void updateChildren (RData *new_children);
RObjectMap childmap;
- RKRowNames *rownames_object;
// why do I need this to make it compile?!
friend class RObjectList;
friend class RObject;
Modified: trunk/rkward/rkward/core/renvironmentobject.cpp
===================================================================
--- trunk/rkward/rkward/core/renvironmentobject.cpp 2013-02-22 10:18:58 UTC (rev 4551)
+++ trunk/rkward/rkward/core/renvironmentobject.cpp 2013-02-22 16:07:50 UTC (rev 4552)
@@ -32,7 +32,6 @@
REnvironmentObject::REnvironmentObject (RContainerObject *parent, const QString &name) : RContainerObject (parent, name) {
RK_TRACE (OBJECTS);
- namespace_envir = 0;
type = Environment;
if (parent == RObjectList::getObjectList ()) {
type |= ToplevelEnv;
@@ -46,7 +45,6 @@
REnvironmentObject::~REnvironmentObject () {
RK_TRACE (OBJECTS);
- delete namespace_envir;
}
QString REnvironmentObject::packageName () const {
@@ -176,14 +174,13 @@
RK_TRACE (OBJECTS);
if (!new_data) {
- if (namespace_envir) {
- RKGlobals::tracker ()->removeObject (namespace_envir, 0, true);
- }
+ setSpecialChildObject (0, NamespaceObject);
return;
}
RK_ASSERT (new_data->getDataType () == RData::StructureVector);
bool added = false;
+ REnvironmentObject *namespace_envir = namespaceEnvironment ();
if (!namespace_envir) {
namespace_envir = new RKNamespaceObject (this);
added = true;
@@ -192,13 +189,7 @@
namespace_envir->updateStructure (new_data->structureVector ().at (0));
if (added) {
RKGlobals::tracker ()->lockUpdates (false);
-
- int index = getObjectModelIndexOf (namespace_envir);
- REnvironmentObject *neo = namespace_envir;
- namespace_envir = 0; // HACK: Must not be included in the count during the call to beginAddObject
- RKGlobals::tracker ()->beginAddObject (neo, this, index);
- namespace_envir = neo;
- RKGlobals::tracker ()->endAddObject (neo, this, index);
+ setSpecialChildObject (namespace_envir, NamespaceObject);
}
}
Modified: trunk/rkward/rkward/core/renvironmentobject.h
===================================================================
--- trunk/rkward/rkward/core/renvironmentobject.h 2013-02-22 10:18:58 UTC (rev 4551)
+++ trunk/rkward/rkward/core/renvironmentobject.h 2013-02-22 16:07:50 UTC (rev 4552)
@@ -42,8 +42,6 @@
/** reimplemented from RContainerObject: If this is an environment var, call RContainerObject::writeMetaData (). Else, do nothing. An environment has no meta data. */
void writeMetaData (RCommandChain *chain);
QString packageName () const;
-/** For the environment of packages with a namespace, return the namespace. May be NULL! */
- REnvironmentObject* namespaceEnvironment () const { return namespace_envir; };
protected:
bool updateStructure (RData *new_data);
/// reimplemented from RContainerObject to call "remove (objectname)" instead of "objectname <- NULL"
@@ -51,8 +49,6 @@
/// reimplemented from RContainerObject to call "remove (objectname)" instead of "objectname <- NULL"
QString renameChildCommand (RObject *object, const QString &new_name) const;
friend class RObject;
- REnvironmentObject *namespace_envir;
-
void updateNamespace (RData *new_data);
};
Modified: trunk/rkward/rkward/core/rkmodificationtracker.cpp
===================================================================
--- trunk/rkward/rkward/core/rkmodificationtracker.cpp 2013-02-22 10:18:58 UTC (rev 4551)
+++ trunk/rkward/rkward/core/rkmodificationtracker.cpp 2013-02-22 16:07:50 UTC (rev 4552)
@@ -2,7 +2,7 @@
rkmodificationtracker - description
-------------------
begin : Tue Aug 31 2004
- copyright : (C) 2004, 2007, 2009, 2010, 2011 by Thomas Friedrichsmeier
+ copyright : (C) 2004-2013 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -94,8 +94,9 @@
RK_ASSERT (object);
RK_ASSERT (object->parentObject ());
+ bool view_update = !updates_locked && !object->isType (RObject::NonVisibleObject);
- if (!updates_locked) {
+ if (view_update) {
QModelIndex object_index = indexFor (object->parentObject ());
int object_row = object->parentObject ()->getObjectModelIndexOf (object);
RK_ASSERT (object_row >= 0);
@@ -106,7 +107,7 @@
object->remove (removed_in_workspace);
- if (!updates_locked) endRemoveRows ();
+ if (view_update) endRemoveRows ();
return true;
}
Modified: trunk/rkward/rkward/core/rkpseudoobjects.h
===================================================================
--- trunk/rkward/rkward/core/rkpseudoobjects.h 2013-02-22 10:18:58 UTC (rev 4551)
+++ trunk/rkward/rkward/core/rkpseudoobjects.h 2013-02-22 16:07:50 UTC (rev 4552)
@@ -21,7 +21,6 @@
#include "renvironmentobject.h"
/** TODO:
- * - use QHashes, instead of class memebers to store slots objects and package namespace objects (and rownames objects)
* - implement OrphanNamepacesObject
* - override getObjectDescription()
* - namespace objects should keep track of their namespace name, themselves
Modified: trunk/rkward/rkward/core/rkrownames.cpp
===================================================================
--- trunk/rkward/rkward/core/rkrownames.cpp 2013-02-22 10:18:58 UTC (rev 4551)
+++ trunk/rkward/rkward/core/rkrownames.cpp 2013-02-22 16:07:50 UTC (rev 4552)
@@ -2,7 +2,7 @@
rkrownames - description
-------------------
begin : Tue Mar 21 2010
- copyright : (C) 2010 by Thomas Friedrichsmeier
+ copyright : (C) 2010, 2013 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -31,7 +31,8 @@
RKRowNames::RKRowNames (RContainerObject *parent) : RKVariable (parent, QString ()) {
RK_TRACE (OBJECTS);
- type = Variable | NonVisibleObject;
+ type = Variable | NonVisibleObject | PseudoObject;
+ pseudo_object_types.insert (this, RowNamesObject);
setDataType (RObject::DataCharacter);
check_duplicates = true;
@@ -42,6 +43,7 @@
RKRowNames::~RKRowNames () {
RK_TRACE (OBJECTS);
+ pseudo_object_types.remove (this);
}
void RKRowNames::beginEdit () {
Modified: trunk/rkward/rkward/core/robject.cpp
===================================================================
--- trunk/rkward/rkward/core/robject.cpp 2013-02-22 10:18:58 UTC (rev 4551)
+++ trunk/rkward/rkward/core/robject.cpp 2013-02-22 16:07:50 UTC (rev 4552)
@@ -2,7 +2,7 @@
robject - description
-------------------
begin : Thu Aug 19 2004
- copyright : (C) 2004, 2006, 2007, 2009, 2010, 2011 by Thomas Friedrichsmeier
+ copyright : (C) 2004-2013 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -41,6 +41,9 @@
// static
QHash<const RObject*, RObject::PseudoObjectType> RObject::pseudo_object_types;
+QHash<const RObject*, RSlotsPseudoObject*> RObject::slots_objects;
+QHash<const RObject*, REnvironmentObject*> RObject::namespace_objects;
+QHash<const RObject*, RKRowNames*> RObject::rownames_objects;
RObject::RObject (RObject *parent, const QString &name) {
RK_TRACE (OBJECTS);
@@ -49,7 +52,7 @@
RObject::name = name;
type = 0;
meta_map = 0;
- slots_pseudo_object = 0;
+ contained_objects = 0;
dimensions = RObjectPrivate::dim_null; // safe initialization
}
@@ -57,7 +60,9 @@
RK_TRACE (OBJECTS);
cancelOutstandingCommands ();
- delete slots_pseudo_object;
+ if (hasPseudoObject (SlotsObject)) delete slots_objects.take (this);
+ if (hasPseudoObject (NamespaceObject)) delete namespace_objects.take (this);
+ if (hasPseudoObject (RowNamesObject)) delete rownames_objects.take (this);
}
bool RObject::irregularShortName (const QString &name) {
@@ -85,7 +90,7 @@
RK_TRACE (OBJECTS);
// not a container
if (op == "@") {
- if (slots_pseudo_object) return (slots_pseudo_object->findObjects (path, matches, "$"));
+ if (slotsPseudoObject ()) return (slotsPseudoObject ()->findObjects (path, matches, "$"));
}
return 0;
}
@@ -243,7 +248,8 @@
updateFromR (0);
return;
}
- if (slots_pseudo_object) slots_pseudo_object->fetchMoreIfNeeded (levels);
+ RSlotsPseudoObject *spo = slotsPseudoObject ();
+ if (spo) spo->fetchMoreIfNeeded (levels);
// Note: We do NOT do the same for any namespaceEnvironment, deliberately
if (levels <= 0) return;
if (!isContainer ()) return;
@@ -327,7 +333,7 @@
for (int i = children.size () - 1; i >= 0; --i) {
children[i]->markDataDirty ();
}
- if (this_container->rownames_object) this_container->rownames_object->markDataDirty ();
+ if (this_container->hasPseudoObject (RowNamesObject)) this_container->rowNames ()->markDataDirty ();
}
}
@@ -475,25 +481,20 @@
if (new_data->getDataLength ()) {
RK_ASSERT (new_data->getDataType () == RData::StructureVector);
bool added = false;
- if (!slots_pseudo_object) {
- slots_pseudo_object = new RSlotsPseudoObject (this);
+ RSlotsPseudoObject *spo = slotsPseudoObject ();
+ if (!spo) {
+ spo = new RSlotsPseudoObject (this);
added = true;
RKGlobals::tracker ()->lockUpdates (true);
}
- bool ret = slots_pseudo_object->updateStructure (new_data->structureVector ().at (0));
+ bool ret = spo->updateStructure (new_data->structureVector ().at (0));
if (added) {
RKGlobals::tracker ()->lockUpdates (false);
-
- int index = getObjectModelIndexOf (slots_pseudo_object);
- RSlotsPseudoObject *spo = slots_pseudo_object;
- slots_pseudo_object = 0; // HACK: Must not be included in the count during the call to beginAddObject
- RKGlobals::tracker ()->beginAddObject (spo, this, index);
- slots_pseudo_object = spo;
- RKGlobals::tracker ()->endAddObject (spo, this, index);
+ setSpecialChildObject (spo, SlotsObject);
}
return ret;
- } else if (slots_pseudo_object) {
- RKGlobals::tracker ()->removeObject (slots_pseudo_object, 0, true);
+ } else if (slotsPseudoObject ()) {
+ setSpecialChildObject (0, SlotsObject);
}
return false;
}
@@ -507,12 +508,12 @@
if (pos >= 0) return pos + offset;
offset += static_cast<const RContainerObject*> (this)->childmap.size ();
}
- if (slots_pseudo_object) {
- if (child == slots_pseudo_object) return offset;
+ if (hasPseudoObject (SlotsObject)) {
+ if (child == slotsPseudoObject ()) return offset;
offset += 1;
}
- if (isType (Environment) && static_cast<const REnvironmentObject*> (this)->namespaceEnvironment ()) {
- if (child == static_cast<const REnvironmentObject*> (this)->namespaceEnvironment ()) return offset;
+ if (hasPseudoObject (NamespaceObject)) {
+ if (child == namespaceEnvironment ()) return offset;
offset += 1;
}
return -1;
@@ -522,23 +523,25 @@
RK_TRACE (OBJECTS);
int ret = isContainer () ? static_cast<const RContainerObject*>(this)->numChildren () : 0;
- if (slots_pseudo_object) ret += 1;
- if (isType (PackageEnv) && static_cast<const REnvironmentObject*>(this)->namespaceEnvironment ()) ret += 1;
+ if (hasPseudoObject (SlotsObject)) ret += 1;
+ if (hasPseudoObject (NamespaceObject)) ret += 1;
return ret;
}
RObject *RObject::findChildByObjectModelIndex (int index) const {
- int offset = index;
if (isContainer ()) {
const RContainerObject *container = static_cast<const RContainerObject*>(this);
if (index < container->numChildren ()) return container->findChildByIndex (index);
- offset -= container->numChildren ();
- if (isType (PackageEnv)) {
- if (offset == 0 && slots_pseudo_object) return slots_pseudo_object;
- return static_cast<const REnvironmentObject*>(this)->namespaceEnvironment ();
- }
+ index -= container->numChildren ();
}
- if (offset == 0) return slots_pseudo_object;
+ if (hasPseudoObject (SlotsObject)) {
+ if (index == 0) return slotsPseudoObject ();
+ --index;
+ }
+ if (hasPseudoObject (NamespaceObject)) {
+ if (index == 0) return namespaceEnvironment ();
+ --index;
+ }
return 0;
}
@@ -552,18 +555,52 @@
static_cast<RContainerObject*> (parent)->renameChild (this, new_short_name);
}
+void RObject::setSpecialChildObject (RObject* special, PseudoObjectType special_type) {
+ RK_TRACE (OBJECTS);
+
+ RObject *old_special = 0;
+ if (special_type == SlotsObject) old_special = slotsPseudoObject ();
+ else if (special_type == NamespaceObject) old_special = namespaceEnvironment ();
+ else if (special_type == RowNamesObject) old_special = rownames_objects.value (this);
+ else RK_ASSERT (false);
+
+ if (special == old_special) return;
+
+ if (old_special) {
+ RKGlobals::tracker ()->removeObject (old_special, 0, true);
+ RK_ASSERT (!hasPseudoObject (special_type)); // should have been removed in the above statement via RObject::remove()
+ }
+
+ if (special) {
+ if (special_type == SlotsObject) slots_objects.insert (this, static_cast<RSlotsPseudoObject*> (special));
+ else if (special_type == NamespaceObject) namespace_objects.insert (this, static_cast<REnvironmentObject*> (special));
+ else if (special_type == RowNamesObject) rownames_objects.insert (this, static_cast<RKRowNames*> (special));
+ contained_objects |= special_type;
+
+ if (special->isType (NonVisibleObject)) return;
+
+ int index = getObjectModelIndexOf (special);
+ // HACK: Newly added object must not be included in the index before beginAddObject (but must be included above for getObjectModelIncexOf() to work)
+ contained_objects -= special_type;
+ RKGlobals::tracker ()->beginAddObject (special, this, index);
+ contained_objects |= special_type;
+ RKGlobals::tracker ()->endAddObject (special, this, index);
+ }
+}
+
void RObject::remove (bool removed_in_workspace) {
RK_TRACE (OBJECTS);
- RK_ASSERT (canRemove ());
+ RK_ASSERT (canRemove () || removed_in_workspace);
- if (isSlotsPseudoObject ()) {
+ if (isPseudoObject ()) {
RK_ASSERT (removed_in_workspace);
- parent->slots_pseudo_object = 0;
+ PseudoObjectType type = getPseudoObjectType ();
+ if (type == SlotsObject) slots_objects.remove (parent);
+ else if (type == NamespaceObject) namespace_objects.remove (parent);
+ else if (type == RowNamesObject) rownames_objects.remove (parent);
+ RK_ASSERT (parent->contained_objects & type);
+ parent->contained_objects -= type;
delete this;
- } else if (isPackageNamespace ()) {
- RK_ASSERT (removed_in_workspace);
- RK_ASSERT (parent->isType (Environment));
- static_cast<REnvironmentObject*> (parent)->namespace_envir = 0;
} else {
static_cast<RContainerObject*> (parent)->removeChild (this, removed_in_workspace);
}
Modified: trunk/rkward/rkward/core/robject.h
===================================================================
--- trunk/rkward/rkward/core/robject.h 2013-02-22 10:18:58 UTC (rev 4551)
+++ trunk/rkward/rkward/core/robject.h 2013-02-22 16:07:50 UTC (rev 4552)
@@ -2,7 +2,7 @@
robject - description
-------------------
begin : Thu Aug 19 2004
- copyright : (C) 2004, 2006, 2007, 2009, 2010, 2011 by Thomas Friedrichsmeier
+ copyright : (C) 2004-2013 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -26,7 +26,9 @@
#include "../rbackend/rcommandreceiver.h"
class RSlotsPseudoObject;
+class REnvironmentObject;
class RContainerObject;
+class RKRowNames;
class RCommandChain;
class RKEditor;
class RData;
@@ -100,10 +102,11 @@
};
enum PseudoObjectType {
- SlotsObject,
- NamespaceObject,
- OrphanNamespacesObject,
- InvalidPseudoObject
+ InvalidPseudoObject = 0,
+ SlotsObject = 1,
+ NamespaceObject = 1 << 1,
+ OrphanNamespacesObject = 1 << 2,
+ RowNamesObject = 1 << 3
};
#define ROBJECT_TYPE_INTERNAL_MASK (RObject::Container | RObject::Variable | RObject::Workspace | RObject::Environment | RObject::Function)
@@ -126,9 +129,10 @@
/** see RObjectType */
bool isType (int type) const { return (RObject::type & type); };
bool isPseudoObject () const { return isType (PseudoObject); };
- static PseudoObjectType getPseudoObjectType (const RObject *object) { return pseudo_object_types.value (object, InvalidPseudoObject); };
- bool isSlotsPseudoObject () const { return (this && isPseudoObject () && (getPseudoObjectType (this) == SlotsObject)); };
- bool isPackageNamespace () const { return (this && isPseudoObject () && (getPseudoObjectType (this) == NamespaceObject)); };
+ PseudoObjectType getPseudoObjectType () const { return pseudo_object_types.value (this, InvalidPseudoObject); };
+ bool isSlotsPseudoObject () const { return (this && isPseudoObject () && (getPseudoObjectType () == SlotsObject)); };
+ bool isPackageNamespace () const { return (this && isPseudoObject () && (getPseudoObjectType () == NamespaceObject)); };
+ bool hasPseudoObject (const PseudoObjectType type) const { return (contained_objects & type); };
bool hasMetaObject () const { return (meta_map); };
/** see RObjectType::Pending */
bool isPending () const { return type & Pending; };
@@ -232,11 +236,17 @@
typedef QList<RObject*> RObjectMap;
RObject *parent;
- RSlotsPseudoObject *slots_pseudo_object;
QString name;
+/** or-ed combination of RObjectType flags for this object */
int type;
QVector<qint32> dimensions;
QStringList classnames;
+/** or-ed combination of PseudoObjectType flags of pseudo objects available in this object */
+ qint8 contained_objects;
+ RSlotsPseudoObject *slotsPseudoObject () const { return (hasPseudoObject (SlotsObject) ? slots_objects.value (this) : 0); };
+/** returns the namespace environment for this object. Always returns 0 for objects which are not a package environment! */
+ REnvironmentObject* namespaceEnvironment () const { return (hasPseudoObject (NamespaceObject) ? namespace_objects.value (this) : 0); };
+ void setSpecialChildObject (RObject *special, PseudoObjectType special_type);
/** Worker function for findObject() and findObjectsMatching(). If matches != 0, look for partial matches, and store them in the map (findObjectsMatching()). Else look for exact matches and return the first match (findObject()). */
virtual RObject *findObjects (const QStringList &path, RObjectSearchMap *matches, const QString &op);
@@ -286,9 +296,18 @@
virtual void endEdit ();
void rCommandDone (RCommand *command);
+
+/* Storage hashes for special objects which are held by some but not all objects, and thus should not have a pointer
+ * in the class declaration. Some apply only to specific RObject types, but moving storage to the relevant classes, would make it more
+ * difficult to maintain the generic bits. */
+ static QHash<const RObject*, RSlotsPseudoObject*> slots_objects;
+ static QHash<const RObject*, REnvironmentObject*> namespace_objects;
+ static QHash<const RObject*, RKRowNames*> rownames_objects;
+
friend class RSlotsPseudoObject;
friend class RKPackageNamespaceObject;
friend class RKOrphanNamespacesObject;
+friend class RKRowNames;
static QHash<const RObject*, PseudoObjectType> pseudo_object_types;
};
More information about the rkward-tracker
mailing list