Skip to content

Commit

Permalink
Merge pull request #102 from SgLy/feat-safe-callback-prop-default
Browse files Browse the repository at this point in the history
feat(core): use safeCallback to call property default function
  • Loading branch information
LastLeaf authored Oct 17, 2023
2 parents 1eb794e + cf7ce5e commit 8ddfb9a
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 17 deletions.
32 changes: 23 additions & 9 deletions glass-easel/src/behavior.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ import {
GetFromObserverPathString,
IsNever,
} from './component_params'
import { FuncArr, triggerWarning } from './func_arr'
import { FuncArr, safeCallback, triggerWarning } from './func_arr'
import { ComponentOptions, getDefaultComponentSpace } from './global_options'
import { MultiPaths, parseMultiPaths } from './data_path'
import { DataValue, DataGroupObserverTree } from './data_proxy'
import {
ComponentDefinition,
GeneralComponent,
GeneralComponentDefinition,
LifetimeFuncs,
Lifetimes,
Expand Down Expand Up @@ -240,9 +241,20 @@ export const convertValueToType = (
value: unknown,
propName: string,
prop: PropertyDefinition,
component: GeneralComponent | null,
): unknown => {
const type = prop.type
const defaultFn = prop.default
const defaultFn =
prop.default === undefined
? undefined
: () =>
safeCallback(
`Property "${propName}" Default`,
prop.default!,
null,
[],
component || undefined,
)
// try match optional types
const optionalTypes = prop.optionalTypes
if (optionalTypes) {
Expand Down Expand Up @@ -507,7 +519,7 @@ export class BehaviorBuilder<
/** @internal */
_$staticData: { [field: string]: any } | undefined = undefined
/** @internal */
_$data: (() => { [field: string]: any })[] = []
_$data: ((component: GeneralComponent) => { [field: string]: any })[] = []
/** @internal */
_$properties?: { name: string; def: PropertyListItem<PropertyType, unknown> }[]
/** @internal */
Expand Down Expand Up @@ -701,7 +713,7 @@ export class BehaviorBuilder<
BehaviorBuilder<T, TData & T, TProperty, TMethod, TChainingFilter, TPendingChainingFilter>,
TChainingFilter
> {
this._$data.push(gen)
this._$data.push((component) => safeCallback('Data Generator', gen, null, [], component) ?? {})
return this as any
}

Expand Down Expand Up @@ -917,7 +929,9 @@ export class BehaviorBuilder<
const rawData = def.data
if (rawData !== undefined) {
if (typeof rawData === 'function') {
this._$data.push(rawData as () => DataList)
this._$data.push(
(component) => safeCallback('Data Generator', rawData, null, [], component) ?? {},
)
} else {
this._$staticData = rawData
}
Expand Down Expand Up @@ -1075,7 +1089,7 @@ export class Behavior<
/** @internal */
_$staticData?: DataList
/** @internal */
_$data: (() => { [field: string]: any })[]
_$data: ((component: GeneralComponent) => { [field: string]: any })[]
/** @internal */
_$propertyMap: { [name: string]: PropertyDefinition }
/** @internal */
Expand Down Expand Up @@ -1436,7 +1450,7 @@ export class Behavior<
// init properties
const properties = builder._$properties
if (properties !== undefined) {
const initValueFuncs: { name: string; func: () => any }[] = []
const initValueFuncs: { name: string; func: (this: null) => any }[] = []
for (let i = 0; i < properties.length; i += 1) {
const { name, def } = properties[i]!
const shortHandDef = normalizePropertyTypeShortHand(def)
Expand Down Expand Up @@ -1513,11 +1527,11 @@ export class Behavior<
func: d.default === undefined ? () => simpleDeepCopy(d.value) : d.default,
})
}
this._$data.push(() => {
this._$data.push((component) => {
const ret: DataList = {}
for (let i = 0; i < initValueFuncs.length; i += 1) {
const { name, func } = initValueFuncs[i]!
ret[name] = func()
ret[name] = safeCallback(`Property "${name}" Default`, func, null, [], component)
}
return ret
})
Expand Down
6 changes: 3 additions & 3 deletions glass-easel/src/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -608,19 +608,19 @@ export class Component<
if (staticData === undefined) {
if (dataGenFuncs.length === 1) {
const f = dataGenFuncs[0]!
data = f()
data = f(comp as unknown as GeneralComponent)
} else {
data = {}
for (let i = 0; i < dataGenFuncs.length; i += 1) {
const f = dataGenFuncs[i]!
Object.assign(data, f())
Object.assign(data, f(comp as unknown as GeneralComponent))
}
}
} else {
data = simpleDeepCopy(staticData)
for (let i = 0; i < dataGenFuncs.length; i += 1) {
const f = dataGenFuncs[i]!
Object.assign(data, f())
Object.assign(data, f(comp as unknown as GeneralComponent))
}
}

Expand Down
7 changes: 6 additions & 1 deletion glass-easel/src/data_proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,12 @@ export class DataGroup<
}
filteredData = oldData
} else {
filteredData = convertValueToType(newData, propName, prop)
filteredData = convertValueToType(
newData,
propName,
prop,
this._$comp as GeneralComponent | null,
)
}
if (!excluded) {
if (this.innerData) {
Expand Down
13 changes: 9 additions & 4 deletions glass-easel/src/func_arr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ export class FuncArr<F extends GeneralFuncType> {
return ret
}

call(caller: ThisType<F>, args: Parameters<F>, relatedComponent?: GeneralComponent): boolean {
call(
caller: ThisParameterType<F>,
args: Parameters<F>,
relatedComponent?: GeneralComponent,
): boolean {
const arr = this._$arr
let ret = true
if (arr) {
Expand All @@ -75,7 +79,7 @@ export class FuncArr<F extends GeneralFuncType> {
this: void,
type: string,
method: F,
caller: ThisType<F>,
caller: ThisParameterType<F>,
args: Parameters<F>,
relatedComponent?: GeneralComponent,
avoidErrorHandler = false,
Expand All @@ -85,7 +89,8 @@ export class FuncArr<F extends GeneralFuncType> {
return method.apply(caller, args)
} catch (e) {
let msg = `[Error] [Component] ${type || 'Error Listener'} Error @ `
if (caller instanceof Component) msg += caller.is
if ((caller as any) instanceof Component) msg += (caller as GeneralComponent).is
else if (relatedComponent instanceof Component) msg += relatedComponent.is
msg += `#${method.name || '(anonymous)'}`
if (relatedComponent) {
relatedComponent.triggerLifetime('error', [e])
Expand Down Expand Up @@ -167,7 +172,7 @@ export class FuncArrWithMeta<F extends GeneralFuncType, T> {
}

call(
caller: ThisType<F>,
caller: ThisParameterType<F>,
args: Parameters<F>,
retainFn: (data: T) => boolean,
relatedComponent?: GeneralComponent,
Expand Down

0 comments on commit 8ddfb9a

Please sign in to comment.