First pass at typescript support
Oh man did this end up requiring a *ton* of other work as well.
There's still a few typing issues I still can't quite work out,
and others I'd like to improve when I have time. In fact, this version
doesn't even really work, it has a stack overflow error caused by
a tooltip for some reason have a tree inside it, which in turn has
another tooltip, etc. There's also 17 errors that I *really* feel like
shouldn't be there, but they are, and 113 warnings - mostly using !
to assert that things are non-null. Lots of work left to do, to sum up.
The reason I'm committing this now is because I really need to get to
work on my game jam, and since it won't use a tree or really many of
TMT-X's features, I can get away with using a broken engine :)
2021-08-17 04:30:54 +00:00
|
|
|
import { computed, isRef } from "vue";
|
|
|
|
import Decimal from "./bignum";
|
|
|
|
import { isFunction, isPlainObject } from "./common";
|
|
|
|
|
|
|
|
export function createLayerProxy(object: Record<string, any>): Record<string, any> {
|
|
|
|
if (object.isProxy) {
|
|
|
|
console.warn(
|
|
|
|
"Creating a proxy out of a proxy! This may cause unintentional function calls and stack overflows."
|
|
|
|
);
|
|
|
|
}
|
|
|
|
const objectProxy = new Proxy(object, layerHandler);
|
|
|
|
travel(createLayerProxy, object, objectProxy);
|
|
|
|
return objectProxy;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function createGridProxy(object: Record<string, any>): Record<string, any> {
|
|
|
|
if (object.isProxy) {
|
|
|
|
console.warn(
|
|
|
|
"Creating a proxy out of a proxy! This may cause unintentional function calls and stack overflows."
|
|
|
|
);
|
|
|
|
}
|
|
|
|
const objectProxy = new Proxy(object, gridHandler);
|
|
|
|
travel(createGridProxy, object, objectProxy);
|
|
|
|
return objectProxy;
|
|
|
|
}
|
|
|
|
|
|
|
|
function travel(
|
|
|
|
callback: (object: Record<string, any>) => void,
|
|
|
|
object: Record<string, any>,
|
|
|
|
objectProxy: Record<string, any>
|
|
|
|
) {
|
|
|
|
for (const key in object) {
|
2021-08-24 13:18:55 +00:00
|
|
|
if (object[key] == undefined || object[key].isProxy || isRef(object[key])) {
|
First pass at typescript support
Oh man did this end up requiring a *ton* of other work as well.
There's still a few typing issues I still can't quite work out,
and others I'd like to improve when I have time. In fact, this version
doesn't even really work, it has a stack overflow error caused by
a tooltip for some reason have a tree inside it, which in turn has
another tooltip, etc. There's also 17 errors that I *really* feel like
shouldn't be there, but they are, and 113 warnings - mostly using !
to assert that things are non-null. Lots of work left to do, to sum up.
The reason I'm committing this now is because I really need to get to
work on my game jam, and since it won't use a tree or really many of
TMT-X's features, I can get away with using a broken engine :)
2021-08-17 04:30:54 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (isFunction(object[key])) {
|
|
|
|
if (
|
|
|
|
(object[key].length !== 0 && object[key].forceCached !== true) ||
|
|
|
|
object[key].forceCached === false
|
|
|
|
) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
object[key] = computed(object[key].bind(objectProxy));
|
|
|
|
} else if (
|
|
|
|
(isPlainObject(object[key]) || Array.isArray(object[key])) &&
|
2021-08-22 06:50:03 +00:00
|
|
|
!(object[key] instanceof Decimal) &&
|
|
|
|
typeof object[key].render !== "function"
|
First pass at typescript support
Oh man did this end up requiring a *ton* of other work as well.
There's still a few typing issues I still can't quite work out,
and others I'd like to improve when I have time. In fact, this version
doesn't even really work, it has a stack overflow error caused by
a tooltip for some reason have a tree inside it, which in turn has
another tooltip, etc. There's also 17 errors that I *really* feel like
shouldn't be there, but they are, and 113 warnings - mostly using !
to assert that things are non-null. Lots of work left to do, to sum up.
The reason I'm committing this now is because I really need to get to
work on my game jam, and since it won't use a tree or really many of
TMT-X's features, I can get away with using a broken engine :)
2021-08-17 04:30:54 +00:00
|
|
|
) {
|
|
|
|
object[key] = callback(object[key]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const layerHandler: ProxyHandler<Record<string, any>> = {
|
|
|
|
get(target: Record<string, any>, key: string, receiver: typeof Proxy): any {
|
|
|
|
if (key === "isProxy") {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (target[key] == undefined) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isRef(target[key])) {
|
|
|
|
return target[key].value;
|
2021-08-22 06:50:03 +00:00
|
|
|
} else if (
|
|
|
|
target[key].isProxy ||
|
|
|
|
target[key] instanceof Decimal ||
|
|
|
|
typeof target[key].render === "function"
|
|
|
|
) {
|
First pass at typescript support
Oh man did this end up requiring a *ton* of other work as well.
There's still a few typing issues I still can't quite work out,
and others I'd like to improve when I have time. In fact, this version
doesn't even really work, it has a stack overflow error caused by
a tooltip for some reason have a tree inside it, which in turn has
another tooltip, etc. There's also 17 errors that I *really* feel like
shouldn't be there, but they are, and 113 warnings - mostly using !
to assert that things are non-null. Lots of work left to do, to sum up.
The reason I'm committing this now is because I really need to get to
work on my game jam, and since it won't use a tree or really many of
TMT-X's features, I can get away with using a broken engine :)
2021-08-17 04:30:54 +00:00
|
|
|
return target[key];
|
|
|
|
} else if (
|
|
|
|
(isPlainObject(target[key]) || Array.isArray(target[key])) &&
|
|
|
|
key.slice(0, 2) !== "__"
|
|
|
|
) {
|
|
|
|
console.warn(
|
|
|
|
"Creating proxy outside `createProxy`. This may cause issues when calling proxied functions.",
|
|
|
|
target,
|
|
|
|
key
|
|
|
|
);
|
|
|
|
target[key] = new Proxy(target[key], layerHandler);
|
|
|
|
return target[key];
|
|
|
|
} else if (isFunction(target[key])) {
|
|
|
|
return target[key].bind(receiver);
|
|
|
|
}
|
|
|
|
return target[key];
|
|
|
|
},
|
|
|
|
set(target: Record<string, any>, key: string, value: any, receiver: typeof Proxy): boolean {
|
|
|
|
if (
|
|
|
|
`${key}Set` in target &&
|
|
|
|
isFunction(target[`${key}Set`]) &&
|
|
|
|
target[`${key}Set`].length < 2
|
|
|
|
) {
|
|
|
|
target[`${key}Set`].call(receiver, value);
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
console.warn(`No setter for "${key}".`, target);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const gridHandler: ProxyHandler<Record<string, any>> = {
|
|
|
|
get(target: Record<string, any>, key: string, receiver: typeof Proxy): any {
|
|
|
|
if (key === "isProxy") {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isRef(target[key])) {
|
|
|
|
return target[key].value;
|
|
|
|
} else if (target[key] && (target[key].isProxy || target[key] instanceof Decimal)) {
|
|
|
|
return target[key];
|
|
|
|
} else if (isPlainObject(target[key]) || Array.isArray(target[key])) {
|
|
|
|
console.warn(
|
|
|
|
"Creating proxy outside `createProxy`. This may cause issues when calling proxied functions.",
|
|
|
|
target,
|
|
|
|
key
|
|
|
|
);
|
|
|
|
target[key] = new Proxy(target[key], layerHandler);
|
|
|
|
return target[key];
|
|
|
|
} else if (isFunction(target[key])) {
|
|
|
|
return target[key].bind(receiver);
|
|
|
|
}
|
|
|
|
if (typeof key !== "symbol" && !isNaN(Number(key))) {
|
|
|
|
target[key] = new Proxy(target, getCellHandler(key));
|
|
|
|
}
|
|
|
|
return target[key];
|
|
|
|
},
|
|
|
|
set(target: Record<string, any>, key: string, value: any, receiver: typeof Proxy): boolean {
|
|
|
|
if (
|
|
|
|
`${key}Set` in target &&
|
|
|
|
isFunction(target[`${key}Set`]) &&
|
|
|
|
target[`${key}Set`].length < 2
|
|
|
|
) {
|
|
|
|
target[`${key}Set`].call(receiver, value);
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
console.warn(`No setter for "${key}".`, target);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
function getCellHandler(id: string) {
|
|
|
|
return {
|
|
|
|
get(target: Record<string, any>, key: string, receiver: typeof Proxy): any {
|
|
|
|
if (key === "isProxy") {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
let prop = target[key];
|
|
|
|
|
|
|
|
if (isFunction(prop) && prop.forceCached === false) {
|
|
|
|
return () => prop.call(receiver, id, target.getData(id));
|
|
|
|
}
|
|
|
|
if (prop != undefined || key.slice == undefined) {
|
|
|
|
return prop;
|
|
|
|
}
|
|
|
|
|
|
|
|
key = key.slice(0, 1).toUpperCase() + key.slice(1);
|
|
|
|
prop = target[`get${key}`];
|
|
|
|
if (isFunction(prop)) {
|
|
|
|
return prop.call(receiver, id, target.getData(id));
|
|
|
|
} else if (prop != undefined) {
|
|
|
|
return prop;
|
|
|
|
}
|
|
|
|
|
|
|
|
prop = target[`on${key}`];
|
|
|
|
if (isFunction(prop)) {
|
|
|
|
return () => prop.call(receiver, id, target.getData(id));
|
|
|
|
} else if (prop != undefined) {
|
|
|
|
return prop;
|
|
|
|
}
|
|
|
|
|
|
|
|
return target[key];
|
|
|
|
},
|
|
|
|
set(target: Record<string, any>, key: string, value: any, receiver: typeof Proxy): boolean {
|
|
|
|
if (
|
|
|
|
`${key}Set` in target &&
|
|
|
|
isFunction(target[`${key}Set`]) &&
|
|
|
|
target[`${key}Set`].length < 3
|
|
|
|
) {
|
|
|
|
target[`${key}Set`].call(receiver, id, value);
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
console.warn(`No setter for "${key}".`, target);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|