-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Updates for version, bitflags, bitfield and default tags. #129
Conversation
Oh, this sounds great! Unfortunately I'm moving and renovating so don't have too much time to review! |
One thing of note, IIRC the xml spec for lists recommends using a blank space as separator rather than a comma. Imo nif xml should be adjusted to adhere to that. |
That is the case for most (I think all) attribute values in the nif xml. In this case that wouldn't be possible because the game names can include spaces (e.g. Skyrim Special Edition). <version id="V3_3_0_13" num="3.3.0.13">{{Munch's Oddysee}}, Oblivion</version> would become <version id="V3_3_0_13" num="3.3.0.13">
<game name="Munch's Oddysee" default="true" />
<game name="Oblivion">
</version> Although as long as you're creating a new tag, you could also do this instead: <version id="V3_3_0_13" num="3.3.0.13" />
<game ID="MUNCH_S_ODDYSEE" default="V3_3_0_13">Munch's Oddysee</game>
<game ID="OBLIVION" default="V20_0_0_5_OBL" nondefault="V3_3_0_13 V10_0_1_0 V10_0_1_2 V10_1_0_101 V10_1_0_106 V10_2_0_0__10">Oblivion</game> Or something similar, where the game is a separate tag that contains information about which versions it appears in, and not the other way around. I don't know which is most useful. If you still want to have the version to contain information about the games, but can't have spaces in attribute names, you could also do something like this: <game id="MUNCH_S_ODDYSEE">Munch's Oddysee</game>
<game id="OBLIVION">Oblivion</game>
<version id="V3_3_0_13" num="3.3.0.13">
<vergame game="MUNCH_S_ODDYSEE" default="true" />
<vergame game="OBLIVION" />
</version> One upside to having separate elements within the version elements (aside from conforming to the spec) would be that you could have a description of the purpose for the different versions in the same game. Of course it does add extra complexity for a feature that, at least at the moment, is almost unused anyways. For now I've just stuck with what was laid out in issue 69. |
…se the correct output type
…ion (as intended).
… different names, and added 'length' and 'width' alias for 'arr1' and 'arr2', respectively.
…sion can use multiple games (separated in the xml by a ', ', and that certain versions may be the default for a particular game. It also uses an enum instead of the game name strings.
…e '10.0.1.0' are converted to their proper integer values (like they are in field attribute conditions)
… defaults are actually respected.
…\\' as their separator.
… the type of the object that the field is on.
…s, so that they can be used when initializing fields.
…are not yet imported.
…ted code (facilitating ≤ from nif.xml).
… (rather than setting an int).
…) from codegen.py.
…-adding or other arithmetic operations). Implemented numeric emulation as documented on https://docs.python.org/3/reference/datamodel.html#emulating-numeric-types
…to tags other than niobject.
… struct/module) and applied them to all tags. Codegen adds __init__.py file to this path where the module attributes are set.
…y are imported again.
…e 73 of nifxml spec: cond is for local variables, vercond for global variables. Updated source xmls accordingly, should not result in a change of generated code (except for nif.xml).
…pression class on Hendrix' recommendation, because they are not used.
Changes
length
andwidth
, respectively, to match with the newer nifxml format.{{...}}
double curly brackets for default versions for a game are now used: set_game checks for them first, and returns after setting it to that version.ver2
attribute is now<=
instead of<
, in line with the intended nifxml function of that attribute.default
tag is now parsed and handled.length
attribute (alias for arr1 used by newer nif.xml). Now does it correctly.cond
andvercond
attributes to be in line with nifxmlspec issue 73.name_filter
argument was dropped from the Expression class, as well as the eval and map_ methods.Detailed changes
,
as in nifxml. get_game() now always returns a list, while set_game() checks whether the game is in the set for that specific version. The version tag is excluded from the apply_conventions() function so that this is easier processed (and the apply_conventions function had no other effect on version tags anyway). This also means that get_game returns a list, rather than a string.context
variable allows for field existence/values on initialization to depend on the version of the file they're created in (which happens in a number of cases in the xml, even fields that change type depending on version).versions
attribute checking, which was necessary for the default tag).≤
) in the xml. This was fixed by setting the encoding toutf-8
. While a rare case, it is theoretically possible to have a non-utf8 encoding for the xml (e.g. utf-16) that will still error when trying to write. If that needs to be addressed, we could take the most permissive encoding between utf-8 and the xml encoding. However, to access the xml encoding, we would have to switch xml parsers from etree to lxml. I've tried it out, and because they are structurally similar it takes very little effort. However, it is not a standard library.int
is immutable, the value used when right-adding (or other arithmetic operations) always used the initialized value (I think). Moreover, the previous implemented numeric emulation functions (such as __add__) edited the value of the bitfield in-place. It has now been changed such that only the actual assignment functions change the bitfield value. The rest of the arithmetic functions simply run the same function on the _value attribute of the object and return the result. The implemented functions are taken from here: https://docs.python.org/3/reference/datamodel.html#emulating-numeric-typesformatname/niobject/modulename
. However, the newer version of nif.xml also applies modules to structs and some enums and bitflags. Therefore, the generated directory structure is nowformatname/modulename/niobject
,formatname/modulename/struct
etc. Moreover, an __init__.py file is added to every module path which sets the attributes __depends__, __priority__ and __custom__ in the module, taken from the attributes depends, priority and custom in the xml. While this information is not necessarily used by anything at the moment, it means they can be accessed.vercond
attribute should only refer to global variables, while thecond
attribute should only refer to local variables. In the old codegen, there was no difference between the evaluation of cond and vercond, and whether a variable was local or global was determined whether it had 'version' in the name. This leads to problems when evaluating the nif.xml, because there is a global variable which does not have this (BS Header\BS Version
). Moreover, it also misclassifies any local variable with 'version' in the name. Hence the update to be in line with the spec, which neatly separates the two.name_filter
argument is only necessary when needing a customisable naming convention. However, all expressions take it from attributes, be that on self or on the context, hence there is no need for this argument. The eval method is used to evaluate an Expression object to an int value, but Expression objects are not used in the generated code, making the eval method obsolete. The map methodis similar. Though it also has potential uses in string manipulation, all necessary ones are already covered in the _parse method.