summaryrefslogtreecommitdiffstats
path: root/data/inst/instance.h
blob: 6b1991b645ad2dbe274505dbd5ed2d512937218f (plain)
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
/* Copyright 2013 MultiMC Contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INSTANCE_H
#define INSTANCE_H

#include <QObject>
#include <QDateTime>

#include "data/appsettings.h"
#include "data/inifile.h"

#define DEFINE_OVERRIDDEN_SETTING_ADVANCED(funcName, cfgEntryName, typeName) \
	typeName get ## funcName() const { return getField(cfgEntryName, settings->get ## funcName()).value<typeName>(); }

#define DEFINE_OVERRIDDEN_SETTING(funcName, typeName) \
	DEFINE_OVERRIDDEN_SETTING_ADVANCED(funcName, STR_VAL(funcName), typeName)

class InstanceList;

/*!
 * \brief Base class for instances.
 * This class implements many functions that are common between instances and 
 * provides a standard interface for all instances.
 * 
 * To create a new instance type, create a new class inheriting from this class
 * and implement the pure virtual functions.
 */
class Instance : public SettingsBase
{
	Q_OBJECT
public:
	explicit Instance(QObject *parent = 0);
	
	// Please, for the sake of my (and everyone else's) sanity, at least keep this shit
	// *somewhat* organized. Also, documentation is semi-important here. Please don't
	// leave undocumented stuff behind.
	
	
	//////// STUFF ////////
	
	/*!
	 * \brief Get the instance's ID. 
	 *        This is a unique identifier string that is, by default, set to the
	 *        instance's folder name. It's not always the instance's folder name, 
	 *        however, as any class deriving from Instance can override the id() 
	 *        method and change how the ID is determined. The instance's ID 
	 *        should always remain constant. Undefined behavior results if an 
	 *        already loaded instance's ID changes.
	 * 
	 * \return The instance's ID.
	 */
	virtual QString id();
	
	/*!
	 * \brief Gets the path to the instance's root directory.
	 * \return  The path to the instance's root directory.
	 */
	virtual QString rootDir();
	
	/*!
	 * \brief Gets the instance list that this instance is a part of. 
	 *        Returns NULL if this instance is not in a list 
	 *        (the parent is not an InstanceList).
	 * \return A pointer to the InstanceList containing this instance. 
	 */
	virtual InstanceList *instList();
	
	
	/*!
	 * \brief Gets this instance's group.
	 *        This function is used by the instance grouping system and should 
	 *        not be touched by classes deriving from Instance.
	 * \return The instance's group name.
	 * \sa setGroup() 
	 */
	QString group() const { return m_group; }
	
	/*!
	 * \brief Sets the instance's group.
	 * \param group The instance's new group name.
	 * \sa group()
	 */
	void setGroup(const QString &group) { m_group = group; emit groupChanged(this, group); }
	
	
	//////// FIELDS AND SETTINGS ////////
	// Fields are options stored in the instance's config file that are specific
	// to instances (not a part of SettingsBase). Settings are things overridden
	// from SettingsBase.
	
	
	////// Fields //////
	
	//// General Info ////
	
	/*!
	 * \brief Gets this instance's name.
	 *        This is the name that will be displayed to the user.
	 * \return The instance's name.
	 * \sa setName
	 */
	virtual QString name() { return getField("name", "Unnamed Instance").value<QString>(); }
	
	/*!
	 * \brief Sets the instance's name
	 * \param val The instance's new name.
	 */
	virtual void setName(QString val) { setField("name", val); }
	
	/*!
	 * \brief Gets the instance's icon key.
	 * \return The instance's icon key.
	 * \sa setIconKey()
	 */
	virtual QString iconKey() const { return getField("iconKey", "default").value<QString>(); }
	
	/*!
	 * \brief Sets the instance's icon key.
	 * \param val The new icon key.
	 */
	virtual void setIconKey(QString val) { setField("iconKey", val); }
	
	
	/*!
	 * \brief Gets the instance's notes.
	 * \return The instances notes.
	 */
	virtual QString notes() const { return getField("notes", "").value<QString>(); }
	
	/*!
	 * \brief Sets the instance's notes.
	 * \param val The instance's new notes.
	 */
	virtual void setNotes(QString val) { setField("notes", val); }
	
	
	/*!
	 * \brief Checks if	the instance's minecraft.jar needs to be rebuilt.
	 *        If this is true, the instance's mods will be reinstalled to its
	 *        minecraft.jar file. This value is automatically set to true when
	 *        the jar mod list changes.
	 * \return Whether or not the instance's jar file should be rebuilt.
	 */
	virtual bool shouldRebuild() const { return getField("NeedsRebuild", false).value<bool>(); }
	
	/*!
	 * \brief Sets whether or not the instance's minecraft.jar needs to be rebuilt.
	 * \param val Whether the instance's minecraft needs to be rebuilt or not.
	 */
	virtual void setShouldRebuild(bool val) { setField("NeedsRebuild", val); }
	
	
	//// Version Stuff ////
	
	/*!
	 * \brief Sets the instance's current version.
	 *        This value represents the instance's current version. If this value
	 *        is different from intendedVersion(), the instance should be updated.
	 *        This value is updated by the updateCurrentVersion() function.
	 * \return A string representing the instance's current version.
	 */
	virtual QString currentVersion() { return getField("JarVersion", "Unknown").value<QString>(); }
	
	/*!
	 * \brief Sets the instance's current version.
	 *        This is used to keep track of the instance's current version. Don't
	 *        mess with this unless you know what you're doing.
	 * \param val The new value.
	 */
	virtual void setCurrentVersion(QString val) { setField("JarVersion", val); }
	
	
	/*!
	 * \brief Gets the version of LWJGL that this instance should use.
	 *        If no LWJGL version is specified in the instance's config file, 
	 *        defaults to "Mojang"
	 * \return The instance's LWJGL version.
	 */
	virtual QString lwjglVersion() { return getField("LwjglVersion", "Mojang").value<QString>(); }
	
	/*!
	 * \brief Sets the version of LWJGL that this instance should use.
	 * \param val The LWJGL version to use
	 */
	virtual void setLWJGLVersion(QString val) { setField("LwjglVersion", val); }
	
	
	/*!
	 * \brief Gets the version that this instance should try to update to.
	 *        If this value differs from currentVersion(), the instance will
	 *        download the intended version when it launches.
	 * \return The instance's intended version.
	 */
	virtual QString intendedVersion() { return getField("IntendedJarVersion", currentVersion()).value<QString>(); }
	
	/*!
	 * \brief Sets the version that this instance should try to update to.
	 * \param val The instance's new intended version.
	 */
	virtual void setIntendedVersion(QString val) { setField("IntendedJarVersion", val); }
	
	
	
	//// Timestamps ////
	
	/*!
	 * \brief Gets the time that the instance was last launched.
	 *        Measured in milliseconds since epoch. QDateTime::currentMSecsSinceEpoch()
	 * \return The time that the instance was last launched.
	 */
	virtual qint64 lastLaunch() { return getField("lastLaunchTime", 0).value<qint64>(); }
	
	/*!
	 * \brief Sets the time that the instance was last launched.
	 * \param val The time to set. Defaults to QDateTime::currentMSecsSinceEpoch()
	 */
	virtual void setLastLaunch(qint64 val = QDateTime::currentMSecsSinceEpoch()) 
	{ setField("lastLaunchTime", val); }
	
	
	////// Settings //////
	
	//// Java Settings ////
	DEFINE_OVERRIDDEN_SETTING_ADVANCED(JavaPath, JPATHKEY, QString)
	DEFINE_OVERRIDDEN_SETTING(JvmArgs, QString)
	
	//// Custom Commands ////
	DEFINE_OVERRIDDEN_SETTING(PreLaunchCommand, QString)
	DEFINE_OVERRIDDEN_SETTING(PostExitCommand, QString)
	
	//// Memory ////
	DEFINE_OVERRIDDEN_SETTING(MinMemAlloc, int)
	DEFINE_OVERRIDDEN_SETTING(MaxMemAlloc, int)
	
	//// Auto login ////
	DEFINE_OVERRIDDEN_SETTING(AutoLogin, bool)
	
	// This little guy here is to keep Qt Creator from being a dumbass and 
	// auto-indenting the lines below the macros. Seriously, it's really annoying.
	;
	
	
	//////// OTHER FUNCTIONS ////////
	
	//// Version System ////
	
	/*!
	 * \brief Checks whether or not the currentVersion of the instance needs to be updated. 
	 *        If this returns true, updateCurrentVersion is called. In the 
	 *        standard instance, this is determined by checking a timestamp 
	 *        stored in the instance config file against the last modified time of Minecraft.jar.
	 * \return True if updateCurrentVersion() should be called.
	 */
	virtual bool shouldUpdateCurrentVersion() = 0;
	
	/*!
	 * \brief Updates the current version. 
	 *        This function should first set the current version timestamp 
	 *        (setCurrentVersionTimestamp()) to the current time. Next, if 
	 *        keepCurrent is false, this function should check what the 
	 *        instance's current version is and call setCurrentVersion() to 
	 *        update it. This function will automatically be called when the 
	 *        instance is loaded if shouldUpdateCurrentVersion returns true.
	 * \param keepCurrent If true, only the version timestamp will be updated.
	 */
	virtual void updateCurrentVersion(bool keepCurrent = false) = 0; 
	
signals:
	/*!
	 * \brief Signal emitted when the instance's group changes.
	 * \param inst Pointer to the instance whose group changed.
	 * \param newGroup The instance's new group.
	 */
	void groupChanged(Instance *inst, QString newGroup);
	
protected:
	/*!
	 * \brief Gets the value of the given field in the instance's config file.
	 *        If the value isn't in the config file, defVal is returned instead.
	 * \param name The name of the field in the config file.
	 * \param defVal The default value.
	 * \return The value of the given field or defVal if the field doesn't exist.
	 * \sa setField()
	 */
	virtual QVariant getField(const QString &name, QVariant defVal = QVariant()) const;
	
	/*!
	 * \brief Sets the value of the given field in the config file.
	 * \param name The name of the field in the config file.
	 * \param val The value to set the field to.
	 * \sa getField()
	 */
	virtual void setField(const QString &name, QVariant val);
	
	// Overrides for SettingBase stuff.
	virtual QVariant getValue(const QString &name, QVariant defVal = QVariant()) const
	{ return settings->getValue(name, defVal); }
	virtual void setValue(const QString &name, QVariant val)
	{ setField(name, val); }
	
	INIFile config;
	
private:
	QString m_group;
};

#endif // INSTANCE_H