[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