-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathCodeAutoComplete.cpp
166 lines (151 loc) · 4.58 KB
/
CodeAutoComplete.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#include "stdafx.h"
#include "ClassBrowser.h"
#include "Compile\ScriptOMAll.h"
#include "Compile\SCISyntaxParser.h"
#include "CodeAutoComplete.h"
#include "SCIPicEditor.h"
using namespace sci;
using namespace std;
AutoCompleteResult GetAutoCompleteResult(SyntaxContext *pContext)
{
// TODO
AutoCompleteResult result;
return result;
}
UINT AutoCompleteThread::s_ThreadWorker(void *pParam)
{
((AutoCompleteThread*)pParam)->_DoWork();
return 0;
}
AutoCompleteThread::AutoCompleteThread()
{
_fDoingWork = false;
_fCancel = false;
_hStartWork = CreateEvent(NULL, FALSE, FALSE, NULL);
_hEndWork = CreateEvent(NULL, FALSE, FALSE, NULL);
_pContext = NULL;
_pLimit = NULL;
_pThread = NULL;
}
AutoCompleteThread::~AutoCompleteThread()
{
if (!_fCancel)
{
Exit();
// phil, this is incomplete... we need to wait until the thread exits, really
}
if (_hStartWork)
{
CloseHandle(_hStartWork);
}
if (_hEndWork)
{
CloseHandle(_hEndWork);
}
}
void AutoCompleteThread::_DoWork()
{
while ((WAIT_OBJECT_0 == WaitForSingleObject(_hStartWork, INFINITE)) && !_fCancel)
{
_it = _itOrig; // Restart from the beginning.
_fDoingWork = true;
sci::Script script;
SyntaxContext context(_it, script);
_pContext = &context;
OutputDebugString("ACThread: PARSE START\n");
//g_Parser.Parse(script, _it, NULL);
//SCISyntaxParser::Instance(LangSyntaxUnknown, theApp._fAllowBraceSyntax).Parse(script, _it, context);
OutputDebugString("ACThread: PARSE END\n");
SetEvent(_hEndWork);
_pContext = NULL;
OutputDebugString("ACThread: waiting to start work...\n");
_fDoingWork = false;
}
ASSERT(FALSE);
}
void AutoCompleteThread::Exit()
{
_fCancel = true;
SetEvent(_hStartWork);
}
CPoint AutoCompleteThread::GetCompletedPosition()
{
LineCol dwPos = _it.GetPosition();
return CPoint(dwPos.Column(), dwPos.Line());
}
void AutoCompleteThread::ResetPosition()
{
OutputDebugString("Resetting position...\n");
_pLimit->Bail();
LineCol dwPos = _it.GetPosition(); // phil, see what this is?
int x = 0;
// We need to wait for it to be done...
OutputDebugString("(RP) Waiting for AC thread to come around... getting stuck here.\n");
if (WAIT_OBJECT_0 == WaitForSingleObject(_hEndWork, INFINITE))
{
// Done
}
else
{
ASSERT(FALSE);
}
}
// Needs to be called when you switch to a new script
void AutoCompleteThread::InitAutoComplete(CCrystalScriptStream::const_iterator it, CScriptStreamLimiter *pLimit)
{
_itOrig = it;
_pLimit = pLimit;
}
AutoCompleteResult AutoCompleteThread::DoAutoComplete(CPoint pt)
{
// Since this thread works directly off the text buffers, make sure all references to text
// are invalidated (we're likely called here, because the user typed a character, which could
// invalidate our pointers to text inside the document)
_pLimit->InvalidateBuffer();
// phil. if this is called, we need to sync here, to wait for it to be done? Unwind to top, since
// we're changing things.
CPoint ptDone = GetCompletedPosition();
if (_pThread && ((pt.y > ptDone.y) || ((pt.y == ptDone.y) && (pt.x > ptDone.x))))
{
OutputDebugString("DAC: Continue where we left off...\n");
_pLimit->Limit(LineCol(pt.y, pt.x));
if (!_fDoingWork)
{
OutputDebugString("DAC: Telling the thread to start work\n");
// Start the work...
SetEvent(_hStartWork);
}
else
{
OutputDebugString("DAC: Telling the limiter to continue..\n");
// We can just continue from where we left off
_pLimit->Continue();
}
// Wait until we hit the end...
_pLimit->Wait();
}
else
{
if (_pThread == NULL)
{
// First time... create the thread... it will wait for the _hStartWork.
_pThread = AfxBeginThread(s_ThreadWorker, this, 0, 0, 0, NULL);
}
else
{
// We need to reset. Tell the parser to bail.
ResetPosition();
}
// Ok, it's been reset, start it anew
_pLimit->Limit(LineCol(pt.y, pt.x));
SetEvent(_hStartWork);
_pLimit->Wait();
}
// We have a result.
AutoCompleteResult result = GetAutoCompleteResult(_pContext);
char sz[100];
StringCchPrintf(sz, ARRAYSIZE(sz), "Completed with %s\n", _pContext->ScratchString().c_str());
OutputDebugString(sz);
// phil, this should probably be an allocated thing...
return result;
}