Suggestion: A Way to Insert Raw Python Code Within EPS
Right now, the only way to include a raw python code within eps code is py_exec or py_eval. However, it is ugly and slow (because it uses exec), and it can be used only under certain circumstances. Can you introduce a way to include python code within eps, like asm in C++?
I'll look at it.
Some considerations are about how the eps code and python code could cleanly interoperate. epScript does a lot of things in a background to resolve differences btw python and epScript. For example, while eps supports nested local scope, python don't well. eps supports local scope by suffixing names. For example, the code below
var a = 1;
function x() {
var a = dwread()[[5]];
a = A[5];
A[a] = 7;
}
is translated as:
a = EUDCreateVariables(1)
_IGVA([a], lambda: [1])
@EUDFunc
def f_x():
a_1 = EUDVariable()
a_1 << (f_dwread()[5])
a_1 << (A[5])
_ARRW(A, a_1) << (7)
The local variable a in eps is translated as a_1 in python code. For inline python code to be useful, eps code should be able to access python variables. I'm wondering how these two features could be interpolated cleanly.
I'm thinking of a syntax like this:
function x() {
py {
a = [x * x for x in range(5)]
}
const aArr = EUDArray(py_a);
}
eps code could access a defined in python namespace by py_a. py_a is translated to a in python source code. Users should handle various pitfalls themselves. (For example you shouldn't redefine a or use plain a in eps code)
Will this suffice? What's your use case?
May I introduce my cases?
// Using Forward in EPS - extra CUnit space
const extra = Db(1700 * 336);
const extra_jump, extra_exit = Forward(), Forward();
function JumpUnitDb() {
py_exec('DoActions([extra_jump << SetMemory(0x6509B0, Add, 0xEDAC])');
}
function ExitUnitDb() {
py_exec('DoActions([extra_exit << SetMemory(0x6509B0, Subtract, 0xEDAC])');
}
function onPluginStart() {
SetMemory(extra_jump + 20, SetTo, (extra - 0x59CCA8) / 4);
SetMemory(extra_exit + 20, SetTo, (extra - 0x59CCA8) / 4);
}
// draw circle
import py_math;
function Circle(t) {
const Period = 32;
EUDSwitch(t);
foreach(i : py_range(Period)) {
EUDSwitchCase()(i);
// can't use py_math (py_math module doesn't have f_cos)
const x = py_eval('int(round(160 * math.cos(i / Period * 2*math.pi)))');
const x = py_eval('int(round(160 * math.sin(i / Period * 2*math.pi)))');
loc.AddLoc($L("effect"), x, y);
const epd = epdread_epd(EPD(0x628438));
CreateUnit(1, "effect", e1 + 1, P8);
dwwrite_epd(epd + 0x110 / 4, 29);
loc.AddLoc($L("effect"), -x, -y);
break;
}
EUDEndSwitch();
}
Right now I am travelling around, so I can't come up with my case very soon. Please refer to Armo's cases. My cases are not very different from his.