Adapt VariablesView to use the ValueNodeManager.
This commit is contained in:
@@ -50,7 +50,7 @@
|
||||
#include "ValueHandlerRoster.h"
|
||||
#include "ValueLocation.h"
|
||||
#include "ValueNode.h"
|
||||
#include "ValueNodeContainer.h"
|
||||
#include "ValueNodeManager.h"
|
||||
#include "Variable.h"
|
||||
#include "VariableValueNodeChild.h"
|
||||
#include "VariablesViewState.h"
|
||||
@@ -451,17 +451,10 @@ private:
|
||||
ValueNodeChild* nodeChild,
|
||||
bool isPresentationNode = false,
|
||||
bool isOnlyChild = false);
|
||||
void _AddNode(Variable* variable);
|
||||
status_t _CreateValueNode(ValueNodeChild* nodeChild);
|
||||
status_t _AddChildNodes(ValueNodeChild* nodeChild);
|
||||
|
||||
// ModelNode* _GetNode(Variable* variable,
|
||||
// TypeComponentPath* path) const;
|
||||
|
||||
private:
|
||||
Thread* fThread;
|
||||
StackFrame* fStackFrame;
|
||||
ValueNodeContainer* fContainer;
|
||||
ValueNodeManager* fNodeManager;
|
||||
ContainerListener* fContainerListener;
|
||||
NodeList fNodes;
|
||||
NodeTable fNodeTable;
|
||||
@@ -841,8 +834,8 @@ VariablesView::ContainerListener::ModelNodeRestoreViewStateRequested(
|
||||
|
||||
VariablesView::VariableTableModel::VariableTableModel()
|
||||
:
|
||||
fStackFrame(NULL),
|
||||
fContainer(NULL),
|
||||
fThread(NULL),
|
||||
fNodeManager(NULL),
|
||||
fContainerListener(NULL),
|
||||
fNodeTable()
|
||||
{
|
||||
@@ -851,13 +844,18 @@ VariablesView::VariableTableModel::VariableTableModel()
|
||||
|
||||
VariablesView::VariableTableModel::~VariableTableModel()
|
||||
{
|
||||
SetStackFrame(NULL, NULL);
|
||||
if (fNodeManager != NULL)
|
||||
fNodeManager->ReleaseReference();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
VariablesView::VariableTableModel::Init()
|
||||
{
|
||||
fNodeManager = new(std::nothrow) ValueNodeManager();
|
||||
if (fNodeManager == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
return fNodeTable.Init();
|
||||
}
|
||||
|
||||
@@ -870,10 +868,8 @@ VariablesView::VariableTableModel::SetContainerListener(
|
||||
return;
|
||||
|
||||
if (fContainerListener != NULL) {
|
||||
if (fContainer != NULL) {
|
||||
AutoLocker<ValueNodeContainer> containerLocker(fContainer);
|
||||
fContainer->RemoveListener(fContainerListener);
|
||||
}
|
||||
if (fNodeManager != NULL)
|
||||
fNodeManager->RemoveListener(fContainerListener);
|
||||
|
||||
fContainerListener->SetModel(NULL);
|
||||
}
|
||||
@@ -883,10 +879,8 @@ VariablesView::VariableTableModel::SetContainerListener(
|
||||
if (fContainerListener != NULL) {
|
||||
fContainerListener->SetModel(this);
|
||||
|
||||
if (fContainer != NULL) {
|
||||
AutoLocker<ValueNodeContainer> containerLocker(fContainer);
|
||||
fContainer->AddListener(fContainerListener);
|
||||
}
|
||||
if (fNodeManager != NULL)
|
||||
fNodeManager->AddListener(fContainerListener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -895,17 +889,9 @@ void
|
||||
VariablesView::VariableTableModel::SetStackFrame(Thread* thread,
|
||||
StackFrame* stackFrame)
|
||||
{
|
||||
if (fContainer != NULL) {
|
||||
AutoLocker<ValueNodeContainer> containerLocker(fContainer);
|
||||
fThread = thread;
|
||||
|
||||
if (fContainerListener != NULL)
|
||||
fContainer->RemoveListener(fContainerListener);
|
||||
|
||||
fContainer->RemoveAllChildren();
|
||||
containerLocker.Unlock();
|
||||
fContainer->ReleaseReference();
|
||||
fContainer = NULL;
|
||||
}
|
||||
fNodeManager->SetStackFrame(thread, stackFrame);
|
||||
|
||||
fNodeTable.Clear(true);
|
||||
|
||||
@@ -917,38 +903,19 @@ VariablesView::VariableTableModel::SetStackFrame(Thread* thread,
|
||||
NotifyNodesRemoved(TreeTablePath(), 0, count);
|
||||
}
|
||||
|
||||
fStackFrame = stackFrame;
|
||||
fThread = thread;
|
||||
if (stackFrame == NULL)
|
||||
return;
|
||||
|
||||
if (fStackFrame != NULL) {
|
||||
fContainer = new(std::nothrow) ValueNodeContainer;
|
||||
if (fContainer == NULL)
|
||||
return;
|
||||
ValueNodeContainer* container = fNodeManager->GetContainer();
|
||||
AutoLocker<ValueNodeContainer> containerLocker(container);
|
||||
|
||||
status_t error = fContainer->Init();
|
||||
if (error != B_OK) {
|
||||
delete fContainer;
|
||||
fContainer = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
AutoLocker<ValueNodeContainer> containerLocker(fContainer);
|
||||
|
||||
if (fContainerListener != NULL)
|
||||
fContainer->AddListener(fContainerListener);
|
||||
|
||||
for (int32 i = 0; Variable* variable = fStackFrame->ParameterAt(i);
|
||||
i++) {
|
||||
_AddNode(variable);
|
||||
}
|
||||
|
||||
for (int32 i = 0; Variable* variable
|
||||
= fStackFrame->LocalVariableAt(i); i++) {
|
||||
_AddNode(variable);
|
||||
}
|
||||
|
||||
// if (!fNodes.IsEmpty())
|
||||
// NotifyNodesAdded(TreeTablePath(), 0, fNodes.CountItems());
|
||||
for (int32 i = 0; i < container->CountChildren(); i++) {
|
||||
VariableValueNodeChild* child = dynamic_cast<VariableValueNodeChild *>(
|
||||
container->ChildAt(i));
|
||||
_AddNode(child->GetVariable(), NULL, child);
|
||||
// top level nodes get their children added immediately
|
||||
// so those won't invoke our callback hook. Add them directly here.
|
||||
ValueNodeChildrenCreated(child->Node());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -957,19 +924,14 @@ void
|
||||
VariablesView::VariableTableModel::ValueNodeChanged(ValueNodeChild* nodeChild,
|
||||
ValueNode* oldNode, ValueNode* newNode)
|
||||
{
|
||||
if (fContainer == NULL)
|
||||
return;
|
||||
|
||||
AutoLocker<ValueNodeContainer> containerLocker(fContainer);
|
||||
AutoLocker<ValueNodeContainer> containerLocker(
|
||||
fNodeManager->GetContainer());
|
||||
ModelNode* modelNode = fNodeTable.Lookup(nodeChild);
|
||||
if (modelNode == NULL)
|
||||
return;
|
||||
|
||||
if (oldNode != NULL) {
|
||||
ValueNodeChildrenDeleted(oldNode);
|
||||
newNode->CreateChildren();
|
||||
if (oldNode != NULL)
|
||||
NotifyNodeChanged(modelNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -977,10 +939,8 @@ void
|
||||
VariablesView::VariableTableModel::ValueNodeChildrenCreated(
|
||||
ValueNode* valueNode)
|
||||
{
|
||||
if (fContainer == NULL)
|
||||
return;
|
||||
|
||||
AutoLocker<ValueNodeContainer> containerLocker(fContainer);
|
||||
AutoLocker<ValueNodeContainer> containerLocker(
|
||||
fNodeManager->GetContainer());
|
||||
|
||||
// check whether we know the node
|
||||
ValueNodeChild* nodeChild = valueNode->NodeChild();
|
||||
@@ -1016,10 +976,8 @@ VariablesView::VariableTableModel::ValueNodeChildrenCreated(
|
||||
void
|
||||
VariablesView::VariableTableModel::ValueNodeChildrenDeleted(ValueNode* node)
|
||||
{
|
||||
if (fContainer == NULL)
|
||||
return;
|
||||
|
||||
AutoLocker<ValueNodeContainer> containerLocker(fContainer);
|
||||
AutoLocker<ValueNodeContainer> containerLocker(
|
||||
fNodeManager->GetContainer());
|
||||
|
||||
// check whether we know the node
|
||||
ValueNodeChild* nodeChild = node->NodeChild();
|
||||
@@ -1058,10 +1016,8 @@ VariablesView::VariableTableModel::ValueNodeChildrenDeleted(ValueNode* node)
|
||||
void
|
||||
VariablesView::VariableTableModel::ValueNodeValueChanged(ValueNode* valueNode)
|
||||
{
|
||||
if (fContainer == NULL)
|
||||
return;
|
||||
|
||||
AutoLocker<ValueNodeContainer> containerLocker(fContainer);
|
||||
AutoLocker<ValueNodeContainer> containerLocker(
|
||||
fNodeManager->GetContainer());
|
||||
|
||||
// check whether we know the node
|
||||
ValueNodeChild* nodeChild = valueNode->NodeChild();
|
||||
@@ -1072,19 +1028,6 @@ VariablesView::VariableTableModel::ValueNodeValueChanged(ValueNode* valueNode)
|
||||
if (modelNode == NULL)
|
||||
return;
|
||||
|
||||
if (valueNode->ChildCreationNeedsValue()
|
||||
&& !valueNode->ChildrenCreated()) {
|
||||
status_t error = valueNode->CreateChildren();
|
||||
if (error != B_OK)
|
||||
return;
|
||||
|
||||
for (int32 i = 0; i < valueNode->CountChildren(); i++) {
|
||||
ValueNodeChild* child = valueNode->ChildAt(i);
|
||||
_CreateValueNode(child);
|
||||
_AddChildNodes(child);
|
||||
}
|
||||
}
|
||||
|
||||
// check whether the value actually changed
|
||||
Value* value = valueNode->GetValue();
|
||||
if (value == modelNode->GetValue())
|
||||
@@ -1214,11 +1157,8 @@ VariablesView::VariableTableModel::GetValueAt(void* object, int32 columnIndex,
|
||||
void
|
||||
VariablesView::VariableTableModel::NodeExpanded(ModelNode* node)
|
||||
{
|
||||
if (fContainer == NULL)
|
||||
return;
|
||||
|
||||
AutoLocker<ValueNodeContainer> containerLocker(fContainer);
|
||||
|
||||
AutoLocker<ValueNodeContainer> containerLocker(
|
||||
fNodeManager->GetContainer());
|
||||
// add children of all children
|
||||
|
||||
// If the node only has a hidden child, add the child's children instead.
|
||||
@@ -1230,7 +1170,7 @@ VariablesView::VariableTableModel::NodeExpanded(ModelNode* node)
|
||||
|
||||
// add the children
|
||||
for (int32 i = 0; ModelNode* child = node->ChildAt(i); i++)
|
||||
_AddChildNodes(child->NodeChild());
|
||||
fNodeManager->AddChildNodes(child->NodeChild());
|
||||
}
|
||||
|
||||
|
||||
@@ -1365,150 +1305,12 @@ VariablesView::VariableTableModel::_AddNode(Variable* variable,
|
||||
|
||||
// if the node is hidden, add its children
|
||||
if (node->IsHidden())
|
||||
_AddChildNodes(nodeChild);
|
||||
fNodeManager->AddChildNodes(nodeChild);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VariablesView::VariableTableModel::_AddNode(Variable* variable)
|
||||
{
|
||||
// create the node child for the variable
|
||||
ValueNodeChild* nodeChild = new (std::nothrow) VariableValueNodeChild(
|
||||
variable);
|
||||
BReference<ValueNodeChild> nodeChildReference(nodeChild, true);
|
||||
if (nodeChild == NULL || !fContainer->AddChild(nodeChild)) {
|
||||
delete nodeChild;
|
||||
return;
|
||||
}
|
||||
|
||||
// create the model node
|
||||
status_t error = _AddNode(variable, NULL, nodeChild, false);
|
||||
if (error != B_OK)
|
||||
return;
|
||||
|
||||
// automatically add child nodes for the top level nodes
|
||||
_AddChildNodes(nodeChild);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
VariablesView::VariableTableModel::_CreateValueNode(ValueNodeChild* nodeChild)
|
||||
{
|
||||
if (nodeChild->Node() != NULL)
|
||||
return B_OK;
|
||||
|
||||
// create the node
|
||||
ValueNode* valueNode;
|
||||
status_t error;
|
||||
if (nodeChild->IsInternal()) {
|
||||
error = nodeChild->CreateInternalNode(valueNode);
|
||||
} else {
|
||||
error = TypeHandlerRoster::Default()->CreateValueNode(nodeChild,
|
||||
nodeChild->GetType(), valueNode);
|
||||
}
|
||||
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
nodeChild->SetNode(valueNode);
|
||||
valueNode->ReleaseReference();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
VariablesView::VariableTableModel::_AddChildNodes(ValueNodeChild* nodeChild)
|
||||
{
|
||||
// create a value node for the value node child, if doesn't have one yet
|
||||
ValueNode* valueNode = nodeChild->Node();
|
||||
if (valueNode == NULL) {
|
||||
status_t error = _CreateValueNode(nodeChild);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
valueNode = nodeChild->Node();
|
||||
}
|
||||
|
||||
// check if this node requires child creation
|
||||
// to be deferred until after its location/value have been resolved
|
||||
if (valueNode->ChildCreationNeedsValue())
|
||||
return B_OK;
|
||||
|
||||
// create the children, if not done yet
|
||||
if (valueNode->ChildrenCreated())
|
||||
return B_OK;
|
||||
|
||||
return valueNode->CreateChildren();
|
||||
}
|
||||
|
||||
|
||||
//VariablesView::ModelNode*
|
||||
//VariablesView::VariableTableModel::_GetNode(Variable* variable,
|
||||
// TypeComponentPath* path) const
|
||||
//{
|
||||
// // find the variable node
|
||||
// ModelNode* node;
|
||||
// for (int32 i = 0; (node = fNodes.ItemAt(i)) != NULL; i++) {
|
||||
// if (node->GetVariable() == variable)
|
||||
// break;
|
||||
// }
|
||||
// if (node == NULL)
|
||||
// return NULL;
|
||||
//
|
||||
// // Now walk along the path, finding the respective child node for each
|
||||
// // component (might be several components at once).
|
||||
// int32 componentCount = path->CountComponents();
|
||||
// for (int32 i = 0; i < componentCount;) {
|
||||
// ModelNode* childNode = NULL;
|
||||
//
|
||||
// for (int32 k = 0; (childNode = node->ChildAt(k)) != NULL; k++) {
|
||||
// TypeComponentPath* childPath = childNode->Path();
|
||||
// int32 childComponentCount = childPath->CountComponents();
|
||||
// if (childComponentCount > componentCount)
|
||||
// continue;
|
||||
//
|
||||
// for (int32 componentIndex = i;
|
||||
// componentIndex < childComponentCount; componentIndex++) {
|
||||
// TypeComponent childComponent
|
||||
// = childPath->ComponentAt(componentIndex);
|
||||
// TypeComponent pathComponent
|
||||
// = path->ComponentAt(componentIndex);
|
||||
// if (childComponent != pathComponent) {
|
||||
// if (componentIndex + 1 == childComponentCount
|
||||
// && pathComponent.HasPrefix(childComponent)) {
|
||||
// // The last child component is a prefix of the
|
||||
// // corresponding path component. We consider this a
|
||||
// // match, but need to recheck the component with the
|
||||
// // next node level.
|
||||
// childComponentCount--;
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// // mismatch -- skip the child
|
||||
// childNode = NULL;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (childNode != NULL) {
|
||||
// // got a match -- skip the matched children components
|
||||
// i = childComponentCount;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (childNode == NULL)
|
||||
// return NULL;
|
||||
//
|
||||
// node = childNode;
|
||||
// }
|
||||
//
|
||||
// return node;
|
||||
//}
|
||||
|
||||
|
||||
bool
|
||||
VariablesView::VariableTableModel::GetTreePath(ModelNode* node,
|
||||
TreeTablePath& _path) const
|
||||
|
||||
@@ -21,6 +21,8 @@ public:
|
||||
virtual Type* GetType() const;
|
||||
virtual ValueNode* Parent() const;
|
||||
|
||||
Variable* GetVariable() const { return fVariable; };
|
||||
|
||||
virtual status_t ResolveLocation(ValueLoader* valueLoader,
|
||||
ValueLocation*& _location);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user