1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 1998-2000, Matthes Bender
5  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 
18 /* Component host for CAulScript */
19 
20 #ifndef INC_C4ScriptHost
21 #define INC_C4ScriptHost
22 
23 #include "c4group/C4ComponentHost.h"
24 #include "script/C4Aul.h"
25 #include "script/C4AulAST.h"
26 
27 #include <bitset>
28 
29 // aul script state
30 enum C4AulScriptState
31 {
32 	ASS_NONE,       // nothing
33 	ASS_PREPARSED,  // function list built; CodeSize set
34 	ASS_LINKED,     // includes and appends resolved
35 	ASS_PARSED      // byte code generated
36 };
37 
38 // generic script host for objects
39 class C4ScriptHost: public C4ComponentHost
40 {
41 public:
42 	~C4ScriptHost() override;
Delete()43 	virtual bool Delete() { return false; } // do NOT delete this - it's just a class member!
44 
45 	void Clear();
46 	virtual bool Load(C4Group &hGroup, const char *szFilename,
47 	          const char *szLanguage, C4LangStringTable *pLocalTable);
48 	virtual bool LoadData(const char *szFilename, const char *szData, class C4LangStringTable *pLocalTable);
49 	void Reg2List(C4AulScriptEngine *pEngine); // reg to linked list
GetPropList()50 	virtual C4PropListStatic * GetPropList() { return nullptr; }
GetPropList()51 	const C4PropListStatic *GetPropList() const { return const_cast<C4ScriptHost*>(this)->GetPropList(); }
GetScript()52 	const char *GetScript() const { return Script.getData(); }
IsReady()53 	bool IsReady() { return State == ASS_PARSED; } // whether script calls may be done
54 	// Translate a string using the script's lang table
55 	std::string Translate(const std::string &text) const;
56 	std::list<C4ScriptHost *> SourceScripts;
57 	StdCopyStrBuf ScriptName; // script name
58 
59 	bool IsWarningEnabled(const char *pos, C4AulWarningId warning) const;
60 
61 protected:
62 	C4ScriptHost();
63 	void Unreg(); // remove from list
64 	void MakeScript();
65 	virtual bool ReloadScript(const char *szPath, const char *szLanguage);
66 
67 	bool Preparse(); // preparse script; return if successfull
68 	virtual bool Parse(); // parse preparsed script; return if successfull
69 	virtual void UnLink(); // reset to unlinked state
70 
71 	void UnlinkOwnedFunctions();
72 	void DeleteOwnedPropLists();
73 
74 	void Warn(const char *pMsg, ...) GNUC_FORMAT_ATTRIBUTE_O;
75 
76 	C4AulScriptEngine *Engine{nullptr}; //owning engine
77 	C4ScriptHost *Prev{nullptr}, *Next{nullptr}; // tree structure
78 
79 	std::list<StdCopyStrBuf> Includes; // include list
80 	std::list<StdCopyStrBuf> Appends; // append list
81 
AddEngineFunctions()82 	virtual void AddEngineFunctions() {}; // add any engine functions specific to this script host
83 	void CopyPropList(C4Set<C4Property> & from, C4PropListStatic * to);
84 	bool ResolveIncludes(C4DefList *rDefs); // resolve includes
85 	bool ResolveAppends(C4DefList *rDefs); // resolve appends
86 	void DoAppend(C4Def *def);
87 	bool Resolving; // set while include-resolving, to catch circular includes
88 	bool IncludesResolved;
89 
90 	StdStrBuf Script; // script
91 	C4LangStringTable *stringTable;
92 	C4Set<C4Property> LocalValues;
93 	C4AulScriptState State{ASS_NONE}; // script state
94 
95 	// list of all functions generated from code in this script host
96 	std::vector<C4Value> ownedFunctions;
97 
98 	// list of all static proplists that refer to this script host
99 	// filled in at link time and used to delete all proplists
100 	// in Clear() even in case of cyclic references.
101 	std::vector<C4Value> ownedPropLists;
102 
103 	void EnableWarning(const char *pos, C4AulWarningId warning, bool enable = true);
104 
105 	friend class C4AulParse;
106 	friend class C4AulProfiler;
107 	friend class C4AulScriptEngine;
108 	friend class C4AulDebug;
109 	friend class C4AulCompiler;
110 	friend class C4AulScriptFunc;
111 
112 private:
113 	std::map<const char*, std::bitset<(size_t)C4AulWarningId::WarningCount>> enabledWarnings;
114 	std::unique_ptr<::aul::ast::Script> ast;
115 };
116 
117 // script host for System.ocg scripts and scenario section Objects.c
118 class C4ExtraScriptHost: public C4ScriptHost
119 {
120 	C4Value ParserPropList;
121 public:
122 	C4ExtraScriptHost(C4String *parent_key_name = nullptr);
123 	~C4ExtraScriptHost() override;
124 	void Clear();
125 
Delete()126 	bool Delete() override { return true; }
127 	C4PropListStatic * GetPropList() override;
128 };
129 
130 // script host for scenario section Objects.c
131 class C4ScenarioObjectsScriptHost : public C4ExtraScriptHost
132 {
133 public:
134 	C4ScenarioObjectsScriptHost();
135 };
136 
137 // script host for defs
138 class C4DefScriptHost: public C4ScriptHost
139 {
140 public:
C4DefScriptHost()141 	C4DefScriptHost() : C4ScriptHost() { }
142 
SetDef(C4Def * to_def)143 	void SetDef(C4Def *to_def) { Def=to_def; }
144 	bool Parse() override;
145 	C4PropListStatic * GetPropList() override;
146 protected:
147 	C4Def *Def{nullptr}; // owning def file
148 };
149 
150 
151 // script host for scenario scripts
152 class C4GameScriptHost : public C4ScriptHost
153 {
154 public:
155 	C4GameScriptHost();
156 	~C4GameScriptHost() override;
157 	bool Load(C4Group &, const char *, const char *, C4LangStringTable *) override;
158 	bool LoadData(const char *, const char *, C4LangStringTable *) override;
159 	void Clear();
160 	C4PropListStatic * GetPropList() override;
161 	void Denumerate(C4ValueNumbers * numbers);
162 	C4Value Call(const char *szFunction, C4AulParSet *pPars=nullptr, bool fPassError=false);
163 	C4Value ScenPropList;
164 	C4Value ScenPrototype;
165 	C4Effect * pScenarioEffects = nullptr;
166 };
167 
168 extern C4GameScriptHost GameScript;
169 
170 #endif
171