1/*
2 * Copyright 2012, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef CLI_CONTEXT_H
6#define CLI_CONTEXT_H
7
8
9#include <sys/cdefs.h>
10	// Needed in histedit.h.
11#include <histedit.h>
12
13#include <Locker.h>
14
15#include "Team.h"
16#include "TeamMemoryBlock.h"
17#include "ValueNodeContainer.h"
18
19
20class StackFrame;
21class StackTrace;
22class Team;
23class TeamMemoryBlock;
24class UserInterfaceListener;
25class ValueNodeManager;
26
27
28class CliContext : private Team::Listener,
29	public TeamMemoryBlock::Listener,
30	private ValueNodeContainer::Listener {
31public:
32			enum {
33				EVENT_QUIT							= 0x01,
34				EVENT_USER_INTERRUPT				= 0x02,
35				EVENT_THREAD_ADDED					= 0x04,
36				EVENT_THREAD_REMOVED				= 0x08,
37				EVENT_THREAD_STOPPED				= 0x10,
38				EVENT_THREAD_STACK_TRACE_CHANGED	= 0x20,
39				EVENT_VALUE_NODE_CHANGED			= 0x40,
40				EVENT_TEAM_MEMORY_BLOCK_RETRIEVED	= 0x80
41			};
42
43public:
44								CliContext();
45								~CliContext();
46
47			status_t			Init(Team* team,
48									UserInterfaceListener* listener);
49			void				Cleanup();
50
51			void				Terminating();
52
53			bool				IsTerminating() const	{ return fTerminating; }
54
55			// service methods for the input loop thread follow
56
57			Team*				GetTeam() const	{ return fTeam; }
58			UserInterfaceListener* GetUserInterfaceListener() const
59									{ return fListener; }
60			ValueNodeManager*	GetValueNodeManager() const
61									{ return fNodeManager; }
62			StackTrace*			GetStackTrace() const
63									{ return fCurrentStackTrace; }
64
65			Thread*				CurrentThread() const { return fCurrentThread; }
66			thread_id			CurrentThreadID() const;
67			void				SetCurrentThread(Thread* thread);
68			void				PrintCurrentThread();
69
70			int32				CurrentStackFrameIndex() const
71									{ return fCurrentStackFrameIndex; }
72			void				SetCurrentStackFrameIndex(int32 index);
73
74			TeamMemoryBlock*	CurrentBlock() const { return fCurrentBlock; }
75
76			const char*			PromptUser(const char* prompt);
77			void				AddLineToInputHistory(const char* line);
78
79			void				QuitSession(bool killTeam);
80
81			void				WaitForThreadOrUser();
82			void				WaitForEvents(int32 eventMask);
83			void				ProcessPendingEvents();
84
85private:
86			struct Event;
87
88			typedef DoublyLinkedList<Event> EventList;
89
90private:
91	// Team::Listener
92	virtual	void				ThreadAdded(const Team::ThreadEvent& event);
93	virtual	void				ThreadRemoved(const Team::ThreadEvent& event);
94
95	virtual	void				ThreadStateChanged(
96									const Team::ThreadEvent& event);
97	virtual	void				ThreadStackTraceChanged(
98									const Team::ThreadEvent& event);
99
100	// TeamMemoryBlock::Listener
101	virtual void				MemoryBlockRetrieved(TeamMemoryBlock* block);
102
103	// ValueNodeContainer::Listener
104	virtual	void				ValueNodeChanged(ValueNodeChild* nodeChild,
105									ValueNode* oldNode, ValueNode* newNode);
106	virtual	void				ValueNodeChildrenCreated(ValueNode* node);
107	virtual	void				ValueNodeChildrenDeleted(ValueNode* node);
108	virtual	void				ValueNodeValueChanged(ValueNode* node);
109
110private:
111			void				_QueueEvent(Event* event);
112
113			void				_PrepareToWaitForEvents(uint32 eventMask);
114			uint32				_WaitForEvents();
115			void				_SignalInputLoop(uint32 events);
116
117	static	const char*			_GetPrompt(EditLine* editLine);
118
119private:
120			BLocker				fLock;
121			Team*				fTeam;
122			UserInterfaceListener* fListener;
123			ValueNodeManager*	fNodeManager;
124			EditLine*			fEditLine;
125			History*			fHistory;
126			const char*			fPrompt;
127			sem_id				fBlockingSemaphore;
128			uint32				fInputLoopWaitingForEvents;
129			uint32				fEventsOccurred;
130			bool				fInputLoopWaiting;
131	volatile bool				fTerminating;
132
133			Thread*				fCurrentThread;
134			StackTrace*			fCurrentStackTrace;
135			int32				fCurrentStackFrameIndex;
136			TeamMemoryBlock*	fCurrentBlock;
137
138			EventList			fPendingEvents;
139};
140
141
142#endif	// CLI_CONTEXT_H
143