#Locally execute function.

16 messages · Page 1 of 1 (latest)

round knot
#

I have code where I have a function defined in a seperate file, and I need to run it locally in another file in order for it to access local variables there and set their value. My only solution I have found was to import it and use an eval() to execute it locally. I am using typescript and have the code being bundled via rollup.

#

The function is held in a global array such as ```js

// These 2 arrays are set to the contents of arrays imported from another file

const functions = [
fixThing() {/stuff/},
fixThing2() {/stuff/}
]
const ids = ["Thing","Thing2"]
// Id0.lengths will always equal functions.length

let localVar = 0;

for (let i = 0; i < ids.length; i++) {
// Execute all functions in array
eval(functions[i] + fix${ids[i]}());
}```

round knot
#

Using functions[i].call() is unable to access localVar and throws undefined error.

fast coral
#

Can you show an example of the file with functions and what the array actually looks like
Why can't they be called directly?

round knot
#

I receive an error of that functions[i] is not a function

#

I did not want to share because I am self conscious about my shitty but functional code

./cct.ts

// entity is a local variable in the location 
import { Mod } from "mods/mod";
import { registerModFix } from "./handler";

export function fixCCT() {
    //@ts-expect-error // here since entity is not defined
    if (entity.components.CommandController && !entity.components.CommandController.command.startsWith("return;"))
        //@ts-expect-error // here since entity is not defined
        entity.components.CommandController.command = `return;\n${entity.components.CommandController.command}`;
}

./handler.ts

const functions = {};

export function registerModFix(id, func, when) {
    functions[id] = { func, when };
}

export function runPossibleFixed(now): [{}, string[]] {
    let returnFuncs = {};
    let returnIds = [];
    for (const id in functions) {
        const { func, when } = functions[id];
        if (now == when) {
            returnFuncs[id] = func;
            returnIds.push(id);
        }
    }
    return [returnFuncs, returnIds];
}

// Other file
registerModFix("CCT", fixCCT, "preEntityPlaceDeserialize");```
#

snippet of ./fileNameUnimportant.ts

//...
    // entity is typeof Entity
    const entity = metaBuilding.createEntity({
      root,
      origin: Vector.fromSerializedObject(staticData.origin),
      rotation: staticData.rotation,
      originalRotation: staticData.originalRotation,
      rotationVariant: data.rotationVariant,
      variant: data.variant,
    });

    entity.uid = payload.uid;
    this.deserializeComponents(root, entity, payload.components);
    if (WhoCares.prototype.forceLoad) {
      const fixes = runPossibleFixed("preEntityPlaceDeserialize");
      const preEntityPlaceDeserialize = fixes[0],
      ids = fixes[1];
      for (let i = 0; i < ids.length; i++) {
        eval(preEntityPlaceDeserialize[i] + `fix${ids[i]}()`); // Works perfect. There arent any security issues with this method. Eval is Evil.
        preEntityPlaceDeserialize[i]() // entity is not defined
        preEntityPlaceDeserialize[i].call() // entity is not defined
        new Function(preEntityPlaceDeserialize[i])(); // doesnt execute
      }
    }
//...
#

I am definitely doing this wrong but it worked and i liked it until i realized i was using an eval

#

I want the functions that are registered via registerModFix(...) to be able to access all local varibles in the location they are ran, without passing them to the function explicitly

fast coral
#

preEntityPlaceDeserializei // entity is not defined
preEntityPlaceDeserialize[i].call() // entity is not defined
it uses the scope where the function was declared at (another file)

new Function(preEntityPlaceDeserialize[i])(); // doesnt execute
it executes function fixCCT() { ... } which does nothing on its own (also have to call it)
but another issue is that Function by design doesnt allow accessing variables declared outside

#

so sadly the only way to let it access local variables directly is eval, but passing arguments would be the proper way

round knot
#

it is a funky system, but it is meant to run additional code depending on certain mods installed to the entity before registering and placing it

#

I built it with the hopes of only having to add the following code with a unique LOCATIONID and have everything else modified outside of the code there. js if (WhoCares.prototype.forceLoad) { const fixes = runPossibleFixed("LOCATIONID"); const preEntityPlaceDeserialize = fixes[0], ids = fixes[1]; for (let i = 0; i < ids.length; i++) { eval(preEntityPlaceDeserialize[i] + `fix${ids[i]}()`); } }