Skip to content

Commit 51da97b

Browse files
committed
* Implement CALL
* Set inst = false when blocking
1 parent 38d8c54 commit 51da97b

File tree

6 files changed

+104
-5
lines changed

6 files changed

+104
-5
lines changed

Agent.cpp

+29-3
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,20 @@ Agent::Agent(unsigned char f, unsigned char g, unsigned short s, unsigned int p)
4545
zorder_iter = world.agents.insert(this);
4646
}
4747

48+
void Agent::zotstack() {
49+
std::list<caosVM *>::iterator i = vmstack.begin();
50+
while (i != vmstack.end()) {
51+
world.freeVM(*i);
52+
}
53+
vmstack.clear();
54+
}
55+
56+
4857
Agent::~Agent() {
4958
world.agents.erase(zorder_iter);
5059
if (vm)
5160
world.freeVM(vm);
61+
zotstack();
5262
zotrefs();
5363
if (unid != -1)
5464
world.freeUNID(unid);
@@ -58,13 +68,19 @@ void Agent::moveTo(float _x, float _y) {
5868
x = _x; y = _y;
5969
}
6070

71+
script *Agent::findScript(unsigned short event) {
72+
return world.scriptorium.getScript(family, genus, species, event);
73+
}
74+
6175
void Agent::fireScript(unsigned short event) {
6276
if (dying) return;
6377

64-
script *s = world.scriptorium.getScript(family, genus, species, event);
78+
script *s = findScript(event);
6579
if (!vm) vm = world.getVM(this);
66-
if (vm->fireScript(s, (event == 9)))
80+
if (vm->fireScript(s, (event == 9))) {
6781
vm->setTarg(this);
82+
zotstack();
83+
}
6884

6985
// This slows us down too much :)
7086
#if 0
@@ -171,8 +187,11 @@ void Agent::tick() {
171187
world.freeVM(vm);
172188
vm = NULL;
173189
}
190+
}
191+
if (!vm && !vmstack.empty()) {
192+
vm = vmstack.front();
193+
vmstack.pop_front();
174194
}
175-
176195
}
177196

178197
void Agent::kill() {
@@ -218,4 +237,11 @@ bool agentzorder::operator ()(const Agent *s1, const Agent *s2) const {
218237
return s1->zorder < s2->zorder;
219238
}
220239

240+
void Agent::pushVM(caosVM *newvm) {
241+
assert(newvm);
242+
if (vm)
243+
vmstack.push_front(vm);
244+
vm = newvm;
245+
}
246+
221247
/* vim: set noet: */

Agent.h

+7
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "caosVar.h"
2626
#include "AgentRef.h"
2727
#include <set>
28+
#include <list>
2829

2930
struct agentzorder {
3031
bool operator()(const class Agent *s1, const class Agent *s2) const;
@@ -43,13 +44,16 @@ class Agent {
4344
class caosVM *vm;
4445

4546
void zotrefs();
47+
void zotstack();
4648

4749
bool dying;
4850
int unid;
4951
unsigned int zorder;
5052
unsigned int tickssincelasttimer, timerrate;
5153

5254
std::multiset<Agent *, agentzorder>::iterator zorder_iter;
55+
std::list<caosVM *> vmstack; // for CALL etc
56+
5357

5458
public:
5559
int clac[3]; int clik;
@@ -72,6 +76,7 @@ class Agent {
7276
void fireScript(unsigned short event);
7377
void moveTo(float, float);
7478
void setTimerRate(unsigned int r) { tickssincelasttimer = 0; timerrate = r; }
79+
void pushVM(caosVM *newvm);
7580

7681
Agent(unsigned char f, unsigned char g, unsigned short s, unsigned int p);
7782
virtual ~Agent();
@@ -88,6 +93,8 @@ class Agent {
8893
virtual void setZOrder(unsigned int plane);
8994
virtual unsigned int getZOrder() const { return zorder; }
9095

96+
class script *findScript(unsigned short event);
97+
9198
int getUNID();
9299
std::string identify() const;
93100
};

caosVM.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ inline bool caosVM::isBlocking() {
5656
}
5757

5858
void caosVM::startBlocking(blockCond *whileWhat) {
59+
inst = false;
5960
if (blocking)
6061
throw creaturesException("trying to block with a block condition in-place");
6162
blocking = whileWhat;
@@ -153,7 +154,8 @@ void caosVM::tick() {
153154

154155
void caosVM::runTimeslice(int units) {
155156
timeslice = units;
156-
while (currentscript && (timeslice > 0 || inst)) {
157+
stop_loop = false;
158+
while (currentscript && !stop_loop && (timeslice > 0 || inst)) {
157159
if (isBlocking()) return;
158160
runOp();
159161
}

caosVM.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class caosVM {
9898
script *currentscript;
9999
caosOp *nip, *cip;
100100

101-
bool inst, lock;
101+
bool inst, lock, stop_loop;
102102
int timeslice;
103103

104104
std::vector<vmStackItem> valueStack;
@@ -232,6 +232,7 @@ class caosVM {
232232
void c_ETCH();
233233
void c_EPAS();
234234
void c_NEXT();
235+
void c_CALL();
235236

236237
// debug
237238
void c_TEST_PASS();

caosVM_flow.cpp

+38
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ void caosVM::c_ESEE() {
196196
ETCH (command) family (integer) genus (integer) species (integer)
197197
%pragma parserclass ENUMhelper
198198
%pragma retc -1
199+
%status stub
199200
200201
like ENUM, but iterate through agents OWNR is touching
201202
*/
@@ -215,6 +216,7 @@ void caosVM::c_ETCH() {
215216
EPAS (command) family (integer) genus (integer) species (integer)
216217
%pragma parserclass ENUMhelper
217218
%pragma retc -1
219+
%status stub
218220
219221
like ENUM, but iterate through OWNR vehicle's passengers
220222
*/
@@ -230,4 +232,40 @@ void caosVM::c_EPAS() {
230232
valueStack.push_back(nullv);
231233
}
232234

235+
/**
236+
CALL (command) script_no (integer) p1 (any) p2 (any)
237+
238+
<p>Calls script_no on OWNR, then waits for it to return. The invoked script
239+
will inherit the caller's INST setting, but any changes it makes to it will
240+
be reversed once it returns - so eg if you call a script when in INST mode,
241+
it calls OVEr and returns, you'll still be in INST.</p>
242+
243+
<p>Script variables (VAxx) will not be preserved - you'll have to use OVxx
244+
for any parameters.</p>
245+
*/
246+
void caosVM::c_CALL() {
247+
VM_PARAM_VALUE(p2)
248+
VM_PARAM_VALUE(p1)
249+
VM_PARAM_INTEGER(script_no)
250+
251+
caos_assert(owner);
252+
caos_assert(script_no > 0 && script_no < 65536);
253+
254+
script *s = owner->findScript(script_no);
255+
if (!s) return;
256+
caosVM *newvm = world.getVM(owner);
257+
258+
if (newvm->fireScript(s, false)) {
259+
newvm->setTarg(owner);
260+
newvm->inst = inst;
261+
newvm->_p_[0] = p1;
262+
newvm->_p_[1] = p2;
263+
owner->pushVM(newvm);
264+
} else
265+
world.freeVM(newvm);
266+
267+
stop_loop = true;
268+
}
269+
270+
233271
/* vim: set noet: */

testcall.cos

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
DBG: OUTS "1..n"
2+
3+
NEW: SIMP 3 2 1 "bluebell" 1 0 0
4+
TICK 1
5+
6+
SCRP 3 2 1 9
7+
SETV OV00 0
8+
CALL 42 "hello, world" TARG
9+
DOIF OV00 eq 0
10+
DBG: OUTS "not ok 3 - CALL blocks"
11+
ELSE
12+
DBG: OUTS "ok 3 - CALL blocks"
13+
ENDI
14+
TICK 0
15+
ENDM
16+
17+
SCRP 3 2 1 42
18+
DBG: OUTS "ok 1 - CALL"
19+
DOIF _P1_ ne "hello, world"
20+
DBG: OUTS "not ok 2 - _P1_"
21+
ELSE
22+
DBG: OUTS "ok 2 - _P1_"
23+
ENDI
24+
SETV OV00 1
25+
ENDM

0 commit comments

Comments
 (0)