armoha / euddraft

System for pluginizing eudplib codes.
Other
29 stars 4 forks source link

Decide the semantics of the mutability of `ExprProxy` #142

Closed armoha closed 1 month ago

armoha commented 1 month ago

ExprProxy

ExprProxy is a base class for proxy classes, which are able to wrap both constants and variables.

Reference types

EUDArray, EUDVArray, EUDStruct, EUDStructArray

CUnit, CSprite

Those classes wrap address of object. Addition does not make sense between them. Subtracting two memory addresses results in the distance between the addresses (the output should be integer type).

Mutability

Mutating them would mean redirecting the reference, or becoming null reference. Since there're two major representations of addresses in EUD, ptr and epd, assignment without providing both representations of address will cost non-trivial runtime conversion between ptr and epd. For CUnit and CSprite, which uses epd as representative value (subject of proxy class), ptr is rarely needed so ptr calculation is cached from epd. EUDArray should have used epd as subject, but it wraps ptr and it will be major breaking change to wrap epd instead of ptr. EUDVArray is an array of EUDVariable (a trigger with 0 condition and 1 SetDeaths action) with some fixed fields. It stores element at value field of SetDeaths action and executes its triggers to take out its elements. It requires ptr of trigger to execute trigger (read value), and requires epd of trigger to modify trigger (write value).

It requires low-level knowledge to correctly and efficiently modify those classes (e.g. in EUDLoopUnit2 function, ptr is incremented by 336 and epd is incremented by 84 at the continue point of the loop, which is related to the size of CUnit struct). The current behavior of ExprProxy on assignment operations can be quite confusing and suboptimal so I'm willing to fix on next version:

Value types

TrgUnit, Weapon, UnitOrder, Flingy, Sprite, Image, TrgPlayer, Upgrade, Tech

LocalLocale

eudplib.scdata.offsetmap.EnumMember

Those classes wrap ranged integers. Arithmetic on them does not guarantee valid value of original type.

Mutability

(TBD)

Others

DBString, TrgString, Db, ...

DBString and Db are similar, they are reference types. DBString is subclass of ExprProxy and it always put \0 null terminator at the end (hence named -String). Db is EUDObject and it will put null terminator if str is provided to its constructor, and it won't put null terminators for bytes. TrgString itself is map string id, which is the input of string triggers (DisplayText, PlayWAV etc.). GetMapStringAddr function will convert string id to its starting address (it is constant function if string id is constant).

Backward compatiblity on mutability of ExprProxy

cc @Dr-zzt

Dr-zzt commented 1 month ago

Great ideas! I think allowing assignment to ExprProxy wrapping variable (hereafter typed variable) is acceptable. Though I believe we must carefully design the epScript grammar so that unwanted/unexpected behaviors don't come up - for example, constants should be kept as constants, and make a new typed variable grammar; allow the variable to change only when there is an explicit assignment to the typed variable.

armoha commented 1 month ago

Typed variable feature was introduced in https://github.com/armoha/euddraft/issues/138 and we need to finish which operations are allowed or forbidden on them.

armoha commented 1 month ago

Solved in https://github.com/armoha/eudplib/commit/98f2409c78a839f81fbb8b9e312a1ae508671669