1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef ULTIMA8_KERNEL_USECODE_PROCESS_H
24 #define ULTIMA8_KERNEL_USECODE_PROCESS_H
25 
26 #include "ultima/shared/std/containers.h"
27 #include "ultima/ultima8/misc/classtype.h"
28 #include "ultima/ultima8/misc/pent_include.h"
29 
30 namespace Ultima {
31 namespace Ultima8 {
32 
33 class Debugger;
34 
35 class Process {
36 	friend class Kernel;
37 	friend class Debugger;
38 public:
39 	virtual void run() = 0;
40 
41 	Process(ObjId _itemNum = 0, uint16 type = 0);
~Process()42 	virtual ~Process() { }
43 
ENABLE_RUNTIME_CLASSTYPE_BASE()44 	ENABLE_RUNTIME_CLASSTYPE_BASE()
45 
46 	uint32 getProcessFlags() const {
47 		return _flags;
48 	}
is_active()49 	bool is_active() const {
50 		return (_flags & PROC_ACTIVE);
51 	}
is_terminated()52 	bool is_terminated() const {
53 		return (_flags & (PROC_TERMINATED |
54 		                 PROC_TERM_DEFERRED)) != 0;
55 	}
is_suspended()56 	bool is_suspended() const {
57 		return (_flags & PROC_SUSPENDED) != 0;
58 	}
59 
60 	//! terminate the process and recursively fail all processes waiting for it
61 	void fail();
62 
63 	//! terminate the process. This wakes up all processes waiting for it.
64 	virtual void terminate();
65 
66 	//! terminate next frame
terminateDeferred()67 	void terminateDeferred() {
68 		_flags |= PROC_TERM_DEFERRED;
69 	}
70 
71 	//! run even when paused
setRunPaused()72 	void setRunPaused() {
73 		_flags |= PROC_RUNPAUSED;
74 	};
75 
76 	//! suspend until process 'pid' returns. If pid is 0, suspend indefinitely
77 	void waitFor(ProcId pid);
78 
79 	//! suspend until process returns. If proc is 0, suspend indefinitely
80 	void waitFor(Process *proc);
81 
82 	//! suspend process
83 	void suspend();
84 
85 	//! Wake up when the process we were waiting for has finished
86 	void wakeUp(uint32 result);
87 
88 	//! A hook to add aditional behavior on wakeup, before anything else happens
onWakeUp()89 	virtual void onWakeUp() {};
90 
setItemNum(ObjId it)91 	void setItemNum(ObjId it) {
92 		_itemNum = it;
93 	}
setType(uint16 ty)94 	void setType(uint16 ty) {
95 		_type = ty;
96 	}
setTicksPerRun(uint32 val)97 	void setTicksPerRun(uint32 val) {
98 		_ticksPerRun = val;
99 	}
100 
getPid()101 	ProcId getPid() const {
102 		return _pid;
103 	}
getItemNum()104 	ObjId getItemNum() const {
105 		return _itemNum;
106 	}
getType()107 	uint16 getType() const {
108 		return _type;
109 	}
getTicksPerRun()110 	uint32 getTicksPerRun() const {
111 		return _ticksPerRun;
112 	}
113 
114 	//! dump some info about this process to pout
115 	virtual void dumpInfo() const;
116 
117 	//! load Process data
118 	bool loadData(Common::ReadStream *rs, uint32 version);
119 
120 	//! save Process data
121 	virtual void saveData(Common::WriteStream *ws);
122 
123 	//! Check the waiting processes.  This is used after loading a game.
124 	//! Ensures they are all valid processes and suspended.  Can't be done in
125 	//! loadData because the waiters may not be loaded yet at that point.
126 	bool validateWaiters() const;
127 
128 protected:
129 	//! process id
130 	ProcId _pid;
131 
132 	uint32 _flags;
133 
134 	//! how many kernel ticks between when this process should be run.
135 	//! not saved because it's fixed by process type and game.
136 	uint32 _ticksPerRun;
137 
138 	//! item we are assigned to
139 	ObjId _itemNum;
140 	uint16 _type;
141 
142 	//! process result
143 	uint32 _result;
144 
145 	//! Processes waiting for this one to finish.
146 	//! When this process terminates, awaken them and pass them the result val.
147 	Std::vector<ProcId> _waiting;
148 
149 public:
150 
151 	enum processflags {
152 		PROC_ACTIVE      = 0x0001,   //!< is the process in the run-list?
153 		PROC_SUSPENDED   = 0x0002,   //!< suspended? (because it's waiting)
154 		PROC_TERMINATED  = 0x0004,
155 		PROC_TERM_DEFERRED = 0x0008, //!< automatically call terminate next frame
156 		PROC_FAILED      = 0x0010,
157 		PROC_RUNPAUSED   = 0x0020    //!< run even if game is paused
158 	};
159 
160 };
161 
162 } // End of namespace Ultima8
163 } // End of namespace Ultima
164 
165 #endif
166