Go to QuArK Web Site
QkObjects.pas
Updated 05 Apr 2018
Upper levels:
QuArK Information Base
4. The Source Code
4.5. File-by-file descriptions

 4.5.8. QkObjects.pas

 [ Prev - Up - Next ] 

This file is the core of the object management of QuArK.

For a general introduction about object management, see 'Structure of the program'. This document discusses specific aspects only of the code in QkObjects.pas.


 Index


 Delay loading

Tiglari / Armin - 05 Apr 2018   [ Top ] 

If FFlags contains the bit  ofNotLoadedToMemory  then FNode points to data that give the file and the position of the object inside the file. This is for the delay-loading mechanism. With this mechanism, when an object is loaded, the  FSpecifics  and  FSubElements  fields are filled, but the children in  FSubElements  are "empty" : they are QObject which still sit on the disk. Their FNode fields give the position for later reading. The method  Acces  must be called on them when they need to be actually loaded. You must never try to read  FSpecifics  or  FSubElements  before the object is actually loaded; if you're unsure call  Acces  first.

In the map editor this is often not necessary because the complete subtree of "worldspawn" is always loaded when the map editor opens.


 Copying

Tiglari / Armin - 05 Apr 2018   [ Top ] 

Sometimes an object is not loaded yet when it needs to be saved on disk, typically when you make only a few changes to a complex .QRK or .PAK file. Then instead of loading the object with all its sub-objects, which takes time and consumes memory, we make a binary copy of the part of the original file into the destination file. This is what  Copying  tries to do. It returns False if the object was already loaded, meaning that direct copying is not possible. If  TransfertSource  is  True , the object's FNode is updated so that if it needs to be loaded later in memory, it will be read from the copy instead. This lets the original file be closed, which is necessary in case we are overriting it (which is the case each time we do a normal 'Save').


 TypeInfo

Tiglari / Armin - 05 Apr 2018   [ Top ] 

This class method simply returns the 'extension' of the object. For files, it's the usual extension with the dot; for non-file objects, it should begin with ' : ' (colon). For example for TTreeMapEntity it is ' :e '. This is a class function, but it is virtual; it's a feature that I've only seen possible in Delphi, not in C++. This lets the code below in QkObjects.pas build a list of all the classes ("pointer to class" is something the C++ doesn't know about) and when loading a object from a file or from inside a file we compare the end of the name with all the TypeInfo's of the classes to know which class should be the object we're about to build.


 SpecificsAdd

Armin Rigo - 05 Apr 2018   [ Top ] 

Note: This code has been disabled for stability reasons.

Normally, Specifics are read and written through the Specifics property of objects, which is a Delphi string list, meaning you can do things such as  Specifics['x']:='yz';  to assign the value 'yz' to the specific called 'x'. This actually adds the string 'x=yz' to the list, unless 'x' had already been set to some value previously, in which case it just replaces the existing 'x=...' string with 'x=yz'.

Note that  Specifics['x']:='';  will remove an existing 'x=...' string, and never add a string with just 'x='.

Adding a specific/arg pair directly is also possible :  Specifics.Add('x=yz')  has the same effect as above, but it does not check for a previously set value, so it must not be used unless you are sure this value does not already exist.

At some point, it might be more efficient (for small specific/args) to use  SpecificsAdd(...)  instead of  Specifics.Add(...) .  SpecificsAdd  is a method of QObject. The whole purpose of this routine and its asm code is to spare memory when loading a file : some specifics are repeated numerous times, e.g. in a map a string like "tex=gothic_a1" will appear dozens of times. As Delphi knows about reference-counted strings, what this code does is look for another already existing string which would be identical, and if it finds it, it is reused (and its reference counter is incremented).



Copyright (c) 2022, GNU General Public License by The QuArK (Quake Army Knife) Community - https://quark.sourceforge.io/

 [ Prev - Top - Next ]