"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GetSetFromAddressMacro = void 0;
const sPrimitiveTypes = [
    "u8",
    "u16",
    "u32",
    "u64",
    "s8",
    "s16",
    "s32",
    "s64",
    "f32",
    "f64"
];
const sPrimitiveTypeSizes = [
    1,
    2,
    4,
    8,
    1,
    2,
    4,
    8,
    4,
    8
];
function processMacros(instance) {
    let getFuncTable = {};
    let setFuncTable = {};
    let basePointer = 0;
    if (instance.__base_pointer != null) {
        basePointer = instance.__base_pointer;
    }
    // generate get and set functions for each primitive
    sPrimitiveTypes.forEach((ptype) => {
        let truncated = ptype;
        // cut out the `u` for memory functions
        if (truncated.startsWith('u')) {
            truncated = truncated.slice(1);
        }
        truncated = truncated.toUpperCase();
        getFuncTable[`__${ptype}_`] = (key, index) => {
            if (instance.memory != null) {
                return instance.memory[`rdramRead${truncated}`](instance[key] + basePointer);
            }
            else {
                console.error("Instance does not have IMemory!");
                return null;
            }
        };
        // create functions
        getFuncTable[`__a_${ptype}_`] = (key, index) => {
            if (instance.memory != null) {
                let size = sPrimitiveTypes.indexOf(`${ptype}`);
                size = sPrimitiveTypeSizes[size];
                return instance.memory[`rdramRead${truncated}`](instance[key] + basePointer + (index * size));
            }
            else {
                console.error("Instance does not have IMemory!");
                return null;
            }
        };
        setFuncTable[`__${ptype}_`] = (key, value, index) => {
            if (instance.memory != null) {
                instance.memory[`rdramWrite${truncated}`](instance[key] + basePointer, value);
            }
            else {
                console.error("Instance does not have IMemory!");
            }
        };
        setFuncTable[`__a_${ptype}_`] = (key, index, value) => {
            if (instance.memory != null) {
                let size = sPrimitiveTypes.indexOf(`${ptype}`);
                size = sPrimitiveTypeSizes[size];
                instance.memory[`rdramWrite${truncated}`](instance[key] + basePointer + (index * size), value);
            }
            else {
                console.error("Instance does not have IMemory!");
            }
        };
    });
    // define properties
    Object.keys(instance).forEach((key) => {
        Object.keys(getFuncTable).forEach((startKey) => {
            if (key.startsWith(startKey)) {
                // array
                if (key.startsWith('__a_')) {
                    Object.defineProperty(instance, `Get_${key.substring(startKey.length, key.length)}`, {
                        value: (index) => {
                            return getFuncTable[startKey](key, index);
                        },
                        writable: false
                    });
                    Object.defineProperty(instance, `Set_${key.substring(startKey.length, key.length)}`, {
                        value: (index, value) => {
                            setFuncTable[startKey](key, index, value);
                        },
                        writable: false
                    });
                }
                else {
                    Object.defineProperty(instance, key.substring(startKey.length, key.length), {
                        get: () => {
                            return getFuncTable[startKey](key);
                        },
                        set: (value) => {
                            setFuncTable[startKey](key, value);
                        }
                    });
                }
            }
        });
    });
}
function GetSetFromAddressMacro() {
    return function _GetSetFromAddressMacro(constr) {
        return class extends constr {
            constructor(...args) {
                const p = constr.prototype;
                super(...args);
                Object.setPrototypeOf(this, p);
                processMacros(this);
            }
        };
    };
}
exports.GetSetFromAddressMacro = GetSetFromAddressMacro;
//# sourceMappingURL=SetGetMacro.js.map