armoha / euddraft

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

Array write/compare always call array read #74

Closed armoha closed 2 years ago

armoha commented 2 years ago

Current status

Most of EUDArray and EUDVArray operations are implemented in armoha/eudplib#18 and https://github.com/armoha/eudplib/commit/3a1287507cda4d9988b96e983a22b9d7c61c170c

arr[index] += x; arr[index]++; ++arr[index];
arr[index] -= x; arr[index]--; --arr[index];
arr[index] *= 0;  // only for constants of 0, 1, 2, 4, 8, 16, ...
arr[index] /= 1;  // only for constants of 1, 2, 4, 8, 16, ...
arr[index] %= 1;  // only for constants of 1, 2, 4, 8, 16, ...
arr[index] <<= 1;  // only for constants of 0~31
arr[index] >>= 1;  // only for constants of 0~31
arr[index] &= 1;
arr[index] |= 1;
arr[index] ^= 1;

arr[index] == x, arr[index] != x
arr[index] >= x, arr[index] <= x
arr[index] > x, arr[index] < x

TODO

Should we expose operator for Subtract modifier?

array[index] **= 2;  // TODO: add power operator for epScript

Original issue

All assignment statements except substitution use _ARRW for array types, which actually does NOT use in-place operation, and instead reads array and does binary operation:

array[index]++;  // Same as `array[index] = array[index] + 1;`
++array[index];  // Same as `array[index] = array[index] + 1;`
array[index]--;  // Same as `array[index] = array[index] - 1;`
--array[index];  // Same as `array[index] = array[index] - 1;`
array[index] += 1;  // Same as `array[index] = array[index] + 1;`
array[index] -= 1;  // Same as `array[index] = array[index] - 1;`
array[index] *= 1;  // Same as `array[index] = array[index] * 1;`
array[index] /= 1;  // Same as `array[index] = array[index] / 1;`
array[index] %= 1;  // Same as `array[index] = array[index] % 1;`
array[index] <<= 1;  // Same as `array[index] = array[index] << 1;`
array[index] >>= 1;  // Same as `array[index] = array[index] >> 1;`
array[index] &= 1;  // Same as `array[index] = array[index] & 1;`
array[index] |= 1;  // Same as `array[index] = array[index] | 1;`
array[index] ^= 1;  // Same as `array[index] = array[index] ^ 1;`

Since in-place operations are much more efficient than binary operations for SC triggers, this should be fixed!

We also needs to stop calculating epd_size_of(array_member) * index twice.

armoha commented 2 years ago

Related lines of code: https://github.com/armoha/eudplib/blob/655b18683d262f46a89d7b31b02547da0e37742d/eudplib/epscript/helper.py#L125-L151

class _ARRW:
    def __init__(self, obj, index):
        self.obj = obj
        self.index = index

    def __lshift__(self, r):
        self.obj[self.index] = r

    def __iadd__(self, v):
        ov = self.obj[self.index]
        self.obj[self.index] = ov + v

    def __isub__(self, v):
        ov = self.obj[self.index]
        self.obj[self.index] = ov - v

    def __imul__(self, v):
        ov = self.obj[self.index]
        self.obj[self.index] = ov * v

    def __ifloordiv__(self, v):
        ov = self.obj[self.index]
        self.obj[self.index] = ov // v

    def __iand__(self, v):
        ov = self.obj[self.index]
        self.obj[self.index] = ov & v

    def __ior__(self, v):
        ov = self.obj[self.index]
        self.obj[self.index] = ov | v

    def __ixor__(self, v):
        ov = self.obj[self.index]
        self.obj[self.index] = ov ^ 
armoha commented 2 years ago

https://stackoverflow.com/questions/11987949/how-to-implement-iadd-for-a-python-property

armoha commented 2 years ago

Resolved by https://github.com/armoha/eudplib/commit/3a1287507cda4d9988b96e983a22b9d7c61c170c