More adjustments to CliContext.
- CliContext now listens for value node container events so that commands can request such a wait as well - Implement an event wait mechanism for commands to make use of. Adjust CliStackTrace and CliPrintVariable accordingly.
This commit is contained in:
@@ -118,6 +118,7 @@ CliContext::Init(Team* team, UserInterfaceListener* listener)
|
|||||||
fNodeManager = new(std::nothrow) ValueNodeManager();
|
fNodeManager = new(std::nothrow) ValueNodeManager();
|
||||||
if (fNodeManager == NULL)
|
if (fNodeManager == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
fNodeManager->AddListener(this);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -316,6 +317,25 @@ CliContext::WaitForThreadOrUser()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CliContext::WaitForEvents(int32 eventMask)
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
_PrepareToWaitForEvents(eventMask | EVENT_USER_INTERRUPT);
|
||||||
|
uint32 events = fEventsOccurred;
|
||||||
|
if ((events & eventMask) == 0) {
|
||||||
|
events = _WaitForEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((events & EVENT_QUIT) != 0 || (events & eventMask) != 0) {
|
||||||
|
_SignalInputLoop(eventMask);
|
||||||
|
ProcessPendingEvents();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CliContext::ProcessPendingEvents()
|
CliContext::ProcessPendingEvents()
|
||||||
{
|
{
|
||||||
@@ -404,6 +424,35 @@ CliContext::ThreadStackTraceChanged(const Team::ThreadEvent& threadEvent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CliContext::ValueNodeChanged(ValueNodeChild* nodeChild, ValueNode* oldNode,
|
||||||
|
ValueNode* newNode)
|
||||||
|
{
|
||||||
|
_SignalInputLoop(EVENT_VALUE_NODE_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CliContext::ValueNodeChildrenCreated(ValueNode* node)
|
||||||
|
{
|
||||||
|
_SignalInputLoop(EVENT_VALUE_NODE_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CliContext::ValueNodeChildrenDeleted(ValueNode* node)
|
||||||
|
{
|
||||||
|
_SignalInputLoop(EVENT_VALUE_NODE_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CliContext::ValueNodeValueChanged(ValueNode* oldNode)
|
||||||
|
{
|
||||||
|
_SignalInputLoop(EVENT_VALUE_NODE_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CliContext::_QueueEvent(Event* event)
|
CliContext::_QueueEvent(Event* event)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <Locker.h>
|
#include <Locker.h>
|
||||||
|
|
||||||
#include "Team.h"
|
#include "Team.h"
|
||||||
|
#include "ValueNodeContainer.h"
|
||||||
|
|
||||||
|
|
||||||
class StackFrame;
|
class StackFrame;
|
||||||
@@ -22,7 +23,8 @@ class UserInterfaceListener;
|
|||||||
class ValueNodeManager;
|
class ValueNodeManager;
|
||||||
|
|
||||||
|
|
||||||
class CliContext : private Team::Listener {
|
class CliContext : private Team::Listener,
|
||||||
|
private ValueNodeContainer::Listener {
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
EVENT_QUIT = 0x01,
|
EVENT_QUIT = 0x01,
|
||||||
@@ -30,7 +32,8 @@ public:
|
|||||||
EVENT_THREAD_ADDED = 0x04,
|
EVENT_THREAD_ADDED = 0x04,
|
||||||
EVENT_THREAD_REMOVED = 0x08,
|
EVENT_THREAD_REMOVED = 0x08,
|
||||||
EVENT_THREAD_STOPPED = 0x10,
|
EVENT_THREAD_STOPPED = 0x10,
|
||||||
EVENT_THREAD_STACK_TRACE_CHANGED = 0x20
|
EVENT_THREAD_STACK_TRACE_CHANGED = 0x20,
|
||||||
|
EVENT_VALUE_NODE_CHANGED = 0x40
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -70,6 +73,7 @@ public:
|
|||||||
void QuitSession(bool killTeam);
|
void QuitSession(bool killTeam);
|
||||||
|
|
||||||
void WaitForThreadOrUser();
|
void WaitForThreadOrUser();
|
||||||
|
void WaitForEvents(int32 eventMask);
|
||||||
void ProcessPendingEvents();
|
void ProcessPendingEvents();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -87,6 +91,13 @@ private:
|
|||||||
virtual void ThreadStackTraceChanged(
|
virtual void ThreadStackTraceChanged(
|
||||||
const Team::ThreadEvent& event);
|
const Team::ThreadEvent& event);
|
||||||
|
|
||||||
|
// ValueNodeContainer::Listener
|
||||||
|
virtual void ValueNodeChanged(ValueNodeChild* nodeChild,
|
||||||
|
ValueNode* oldNode, ValueNode* newNode);
|
||||||
|
virtual void ValueNodeChildrenCreated(ValueNode* node);
|
||||||
|
virtual void ValueNodeChildrenDeleted(ValueNode* node);
|
||||||
|
virtual void ValueNodeValueChanged(ValueNode* node);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _QueueEvent(Event* event);
|
void _QueueEvent(Event* event);
|
||||||
|
|
||||||
|
|||||||
@@ -116,16 +116,14 @@ CliPrintVariableCommand::_ResolveValueIfNeeded(ValueNode* node,
|
|||||||
context.GetUserInterfaceListener()->ValueNodeValueRequested(
|
context.GetUserInterfaceListener()->ValueNodeValueRequested(
|
||||||
context.CurrentThread()->GetCpuState(), container, node);
|
context.CurrentThread()->GetCpuState(), container, node);
|
||||||
|
|
||||||
// TODO: implement proper waiting
|
|
||||||
while (!context.IsTerminating()) {
|
while (node->LocationAndValueResolutionState()
|
||||||
context.ProcessPendingEvents();
|
== VALUE_NODE_UNRESOLVED) {
|
||||||
if (node->LocationAndValueResolutionState()
|
|
||||||
!= VALUE_NODE_UNRESOLVED) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
containerLocker.Unlock();
|
containerLocker.Unlock();
|
||||||
snooze(20000);
|
context.WaitForEvents(CliContext::EVENT_VALUE_NODE_CHANGED);
|
||||||
containerLocker.Lock();
|
containerLocker.Lock();
|
||||||
|
if (context.IsTerminating())
|
||||||
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,11 +45,11 @@ CliStackTraceCommand::Execute(int argc, const char* const* argv,
|
|||||||
|
|
||||||
// get its stack trace
|
// get its stack trace
|
||||||
StackTrace* stackTrace = thread->GetStackTrace();
|
StackTrace* stackTrace = thread->GetStackTrace();
|
||||||
if (stackTrace == NULL) {
|
while (stackTrace == NULL) {
|
||||||
// TODO: Wait for stack trace!
|
context.WaitForEvents(CliContext::EVENT_THREAD_STACK_TRACE_CHANGED);
|
||||||
printf("Current thread doesn't have a stack trace. Waiting not "
|
if (context.IsTerminating())
|
||||||
"implemented yet\n");
|
return;
|
||||||
return;
|
stackTrace = thread->GetStackTrace();
|
||||||
}
|
}
|
||||||
BReference<StackTrace> stackTraceReference(stackTrace);
|
BReference<StackTrace> stackTraceReference(stackTrace);
|
||||||
// hold a reference until we're done
|
// hold a reference until we're done
|
||||||
|
|||||||
Reference in New Issue
Block a user