lodash#isNumber TypeScript Examples
The following examples show how to use
lodash#isNumber.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: analysis-utils.ts From prism-frontend with MIT License | 7 votes |
function thresholdOrNaN(value: number, threshold?: ThresholdDefinition) {
// filter out nullish values.
if (!isNumber(value)) {
return NaN;
}
// if there is no threshold, simply return the original value.
if (threshold === undefined) {
return value;
}
const isAbove =
threshold.above === undefined ? true : value >= threshold.above;
const isBelow =
threshold.below === undefined ? true : value <= threshold.below;
return isAbove && isBelow ? value : NaN;
}
Example #2
Source File: utils.tsx From XFlow with MIT License | 7 votes |
createPath = (paths: (string | number)[][], offsetX = 0, offsetY = 0) => {
if (!paths.length) {
return null
}
let path = ''
// @ts-ignore
paths.forEach((item: IPath) => {
const [c, x, y, c2x, c2y] = item
path += isNumber(y) ? ` ${c} ${x + offsetX} ${y + offsetY}` : ` ${c}`
if (c2y) {
path += ` ${c2x + offsetX} ${c2y + offsetY}`
}
})
return path
}
Example #3
Source File: utilities.ts From react-native-jigsaw with MIT License | 7 votes |
export function getValueForRadioButton(value: string | number) {
if (isString(value)) {
return value;
} else if (isNumber(value)) {
return String(value);
} else {
throw new Error(`Invalid value: ${value}`);
}
}
Example #4
Source File: index.tsx From prism-frontend with MIT License | 6 votes |
DataTableRow = ({ className, columns, rowData }: TableRowProps) => {
const { t } = useSafeTranslation();
return (
<TableRow>
{columns.map(column => {
const colValue = rowData ? rowData[column] : column;
const formattedColValue = isNumber(colValue)
? getRoundedData(colValue, t)
: t(colValue).toLocaleString();
return (
<TableCell className={className} key={column}>
{' '}
{formattedColValue}{' '}
</TableCell>
);
})}
</TableRow>
);
}
Example #5
Source File: bleachingAlert.ts From aqualink-app with MIT License | 6 votes |
calculateAlertLevel = (
maxMonthlyMean?: number | null,
satelliteTemperature?: number | null,
degreeHeatingDays?: number | null,
): number | undefined => {
const hotSpot =
satelliteTemperature &&
maxMonthlyMean &&
satelliteTemperature - maxMonthlyMean;
switch (true) {
case isNil(hotSpot):
return undefined;
case isNumber(hotSpot) && hotSpot <= 0:
return 0;
case isNumber(hotSpot) && hotSpot < 1:
return 1;
// Hotspot >=1 or nil past this point, start dhw checks.
case isNil(degreeHeatingDays):
return 0;
case inRange(degreeHeatingDays!, 0, 4 * 7):
return 2;
case inRange(degreeHeatingDays!, 4 * 7, 8 * 7):
return 3;
case degreeHeatingDays! >= 8 * 7:
return 4;
default:
return undefined;
}
}
Example #6
Source File: StarBadge.tsx From hub with Apache License 2.0 | 6 votes |
StarBadge = (props: Props) => {
if (isUndefined(props.starsNumber) || !isNumber(props.starsNumber)) return null;
return (
<div
data-testid="starBadge"
className={classnames('badge rounded-pill bg-light text-dark border', styles.badge, props.className, {
[styles[`size-${props.size}`]]: !isUndefined(props.size),
})}
aria-label={`${props.starsNumber} stars`}
>
<div className="d-flex align-items-center">
<FaStar className={`me-1 ${styles.icon}`} />
<div>{prettifyNumber(props.starsNumber)}</div>
</div>
</div>
);
}
Example #7
Source File: records.ts From ts-di-starter with MIT License | 6 votes |
/**
* Patch record
*
* @param {Request} request
* @returns {Promise<Record>}
*/
async patch(request): Promise<Record> {
assertProperties(request.locals, ['user']);
const { user }: { user: UserModel } = request.locals;
assertProperties(request.params, ['recordId']);
const { recordId }: { recordId: string } = request.params;
const { value } = request.body;
if (!isNumber(value)) {
throw new Err('value must be a number', HTTP_STATUS.BAD_REQUEST);
}
await this.services.records.assertUserRecord(recordId, user.id);
return this.services.records.patch(recordId, value);
}
Example #8
Source File: index.tsx From erda-ui with GNU Affero General Public License v3.0 | 6 votes |
TimeSpanFilterItem = ({
itemData,
value,
active,
onVisibleChange,
onChange,
onQuickOperation,
labels,
}: Merge<IFilterItemProps<'timespanRange'>, { labels: JSX.Element }>) => {
const [duration, setDuration] = React.useState();
useEffectOnce(() => {
setDuration(value);
});
const { key, label, placeholder, disabled } = itemData;
return (
<span className="contractive-filter-item">
{labels}
<Duration
value={duration}
onChange={(v) => {
const durationMin = transformDuration(v?.[0]);
const durationMax = transformDuration(v?.[1]);
if (isNumber(durationMin) && isNumber(durationMax)) {
if (durationMin <= durationMax) {
onChange({ key, value: v });
} else {
message.error(i18n.t('msp:wrong duration'));
}
} else if (!isNumber(durationMin) && !isNumber(durationMax)) {
onChange({ key, value: [] });
}
}}
/>
</span>
);
}
Example #9
Source File: add-edit-mileage.page.ts From fyle-mobile-app with MIT License | 6 votes |
addToNewReport(txnId: string) {
const that = this;
from(this.loaderService.showLoader())
.pipe(
switchMap(() => this.transactionService.getEtxn(txnId)),
finalize(() => from(this.loaderService.hideLoader()))
)
.subscribe((etxn) => {
const criticalPolicyViolated = isNumber(etxn.tx_policy_amount) && etxn.tx_policy_amount < 0.0001;
if (!criticalPolicyViolated) {
that.router.navigate(['/', 'enterprise', 'my_create_report', { txn_ids: JSON.stringify([txnId]) }]);
} else {
that.close();
}
});
}
Example #10
Source File: InputNumber.tsx From gant-design with MIT License | 6 votes |
withInputNumber = compose(
withProps(({ value, onChange, format }) => {
let $value = value;
const notnumber = value && !isNumber(value);
if (notnumber) {
$value = null
}
if (!isNil($value)) {
$value = numeral($value).value()
}
return {
value: $value,
onChange: (val) => {
let numberVal = val;
if (format) {
numberVal = Number(numeral(numberVal).format(format));
}
onChange && onChange(numberVal);
}
}
})
)
Example #11
Source File: update-one-user-search-group.ts From js-client with MIT License | 6 votes |
makeUpdateOneUserSearchGroup = (context: APIContext) => {
return async (userID: NumericID, groupID: NumericID | null): Promise<void> => {
try {
const path = '/api/users/{userID}/searchgroup';
const url = buildURL(path, { ...context, protocol: 'http', pathParams: { userID } });
const body: UpdateOneUserSearchGroupRawRequest = {
GID: isNumber(groupID) ? groupID : isNull(groupID) ? groupID : parseInt(groupID, 10),
};
const baseRequestOptions: HTTPRequestOptions = {
body: JSON.stringify(body),
};
const req = buildHTTPRequestWithAuthFromContext(context, baseRequestOptions);
const raw = await context.fetch(url, { ...req, method: 'PUT' });
return parseJSONResponse(raw, { expect: 'void' });
} catch (err) {
if (err instanceof Error) throw err;
throw Error('Unknown error');
}
};
}
Example #12
Source File: useValue.ts From gio-design with Apache License 2.0 | 6 votes |
formatValue = (isMultiple: boolean, value?: MaybeArray<string | number>) => {
if (isMultiple) {
if (isNil(value)) {
return [];
}
if (isString(value) || isNumber(value)) {
return [value];
}
return value;
}
if (isNil(value)) {
return '';
}
return value;
}
Example #13
Source File: helpers.tsx From leda with MIT License | 6 votes |
getNumericValue = (val?: number | string | undefined): number | null => {
if (!isNil(val)) {
if (isNumber(val)) return val;
const parsedValue = parseFloat(val.replace(/\s/g, '')); // убрать все пробелы из строки
return Number.isNaN(parsedValue) ? null : parsedValue;
}
return null;
}
Example #14
Source File: helpers.ts From querybook with Apache License 2.0 | 6 votes |
export function detectVariableType(value: any): TSupportedTypes {
if (isBoolean(value)) {
return 'boolean';
}
if (isNumber(value)) {
return 'number';
}
return 'string';
}
Example #15
Source File: balance.ts From subscan-multisig-react with Apache License 2.0 | 6 votes |
toString = (value: string | BN | number): string => {
if (BN.isBN(value)) {
return value.toString();
} else if (isString(value)) {
return Number(value).toString(10);
} else if (isNumber(value)) {
return value.toString(10);
} else if (isUndefined(value) || isNaN(value) || isNull(value)) {
return '0';
} else {
throw new TypeError(
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`Can not convert the value ${value} to String type. Value type is ${typeof value}`
);
}
}
Example #16
Source File: processDataFrame.ts From grafana-chinese with Apache License 2.0 | 6 votes |
/**
* Given a value this will guess the best column type
*
* TODO: better Date/Time support! Look for standard date strings?
*/
export function guessFieldTypeFromValue(v: any): FieldType {
if (isNumber(v)) {
return FieldType.number;
}
if (isString(v)) {
if (NUMBER.test(v)) {
return FieldType.number;
}
if (v === 'true' || v === 'TRUE' || v === 'True' || v === 'false' || v === 'FALSE' || v === 'False') {
return FieldType.boolean;
}
return FieldType.string;
}
if (isBoolean(v)) {
return FieldType.boolean;
}
if (v instanceof Date || isDateTime(v)) {
return FieldType.time;
}
return FieldType.other;
}
Example #17
Source File: Kernel.ts From GWebGPUEngine with MIT License | 5 votes |
public setBinding(
name:
| string
| Record<
string,
| number
| number[]
| Float32Array
| Uint8Array
| Uint16Array
| Uint32Array
| Int8Array
| Int16Array
| Int32Array
>,
data?:
| number
| number[]
| Float32Array
| Uint8Array
| Uint16Array
| Uint32Array
| Int8Array
| Int16Array
| Int32Array
| Kernel,
) {
if (typeof name === 'string') {
const isNumberLikeData =
isNumber(data) || isTypedArray(data) || isArray(data);
if (this.compiledBundle && this.compiledBundle.context) {
// set define, eg. setBinding('MAX_LENGTH', 10)
const existedDefine = this.compiledBundle.context.defines.find(
(b) => b.name === name,
);
if (existedDefine) {
existedDefine.value = data as number;
return this;
}
// set uniform
const existedBinding = this.compiledBundle.context.uniforms.find(
(b) => b.name === name,
);
if (existedBinding) {
// update uniform or buffer
if (isNumberLikeData) {
// @ts-ignore
existedBinding.data = data;
existedBinding.isReferer = false;
if (existedBinding.storageClass === STORAGE_CLASS.Uniform) {
if (this.model) {
// @ts-ignore
this.model.updateUniform(name, data);
}
} else {
if (this.model) {
// @ts-ignore
this.model.updateBuffer(name, data);
}
}
} else {
// update with another kernel
existedBinding.isReferer = true;
// @ts-ignore
existedBinding.data = data as Kernel;
}
}
}
} else {
Object.keys(name).forEach((key) => {
this.setBinding(key, name[key]);
});
}
return this;
}
Example #18
Source File: base-cell.ts From S2 with MIT License | 5 votes |
// 根据当前state来更新cell的样式
public updateByState(stateName: InteractionStateName, cell: S2CellType) {
this.spreadsheet.interaction.setInteractedCells(cell);
const stateStyles = get(
this.theme,
`${this.cellType}.cell.interactionState.${stateName}`,
);
const { x, y, height, width } = this.getCellArea();
each(stateStyles, (style, styleKey) => {
const targetShapeNames = keys(
pickBy(SHAPE_ATTRS_MAP, (attrs) => includes(attrs, styleKey)),
);
targetShapeNames.forEach((shapeName: StateShapeLayer) => {
const isStateShape = this.stateShapes.has(shapeName);
const shape = isStateShape
? this.stateShapes.get(shapeName)
: this[shapeName];
// stateShape 默认 visible 为 false
if (isStateShape && !shape.get('visible')) {
shape.set('visible', true);
}
// 根据borderWidth更新borderShape大小 https://github.com/antvis/S2/pull/705
if (
shapeName === 'interactiveBorderShape' &&
styleKey === 'borderWidth'
) {
if (isNumber(style)) {
const marginStyle = {
x: x + style / 2,
y: y + style / 2,
width: width - style - 1,
height: height - style - 1,
};
each(marginStyle, (currentStyle, currentStyleKey) => {
updateShapeAttr(shape, currentStyleKey, currentStyle);
});
}
}
updateShapeAttr(shape, SHAPE_STYLE_MAP[styleKey], style);
});
});
}
Example #19
Source File: dailyData.ts From aqualink-app with MIT License | 5 votes |
export function getMaxAlert(
dailyAlertLevel?: number,
weeklyAlertLevel?: number,
) {
return getMax([weeklyAlertLevel, dailyAlertLevel].filter(isNumber));
}
Example #20
Source File: TemplateEngineManager.tsx From easy-email with MIT License | 5 votes |
function generateConditionTemplate(
option: NonNullable<AdvancedBlock['data']['value']['condition']>,
content: React.ReactElement
) {
const { symbol, groups } = option;
const generateExpression = (condition: {
left: string | number;
operator: Operator;
right: string | number;
}) => {
if (condition.operator === Operator.TRUTHY) {
return condition.left;
}
if (condition.operator === Operator.FALSY) {
return condition.left + ' == nil';
}
return (
condition.left +
' ' +
condition.operator +
' ' +
(isNumber(condition.right) ? condition.right : `"${condition.right}"`)
);
};
const uuid = nanoid(5);
const variables = groups.map((_, index) => `con_${index}_${uuid}`);
const assignExpression = groups
.map((item, index) => {
return `{% assign ${variables[index]} = ${item.groups
.map(generateExpression)
.join(` ${item.symbol} `)} %}`;
})
.join('\n');
const conditionExpression = variables.join(` ${symbol} `);
return (
<Template>
<Raw>
{`
<!-- htmlmin:ignore -->
${assignExpression}
{% if ${conditionExpression} %}
<!-- htmlmin:ignore -->
`}
</Raw>
{content}
<Raw>
{`
<!-- htmlmin:ignore -->
{% endif %}
<!-- htmlmin:ignore -->
`}
</Raw>
</Template>
);
}
Example #21
Source File: ElasticSearchSearchEngine.ts From backstage with Apache License 2.0 | 5 votes |
function isBlank(str: string) {
return (isEmpty(str) && !isNumber(str)) || nan(str);
}
Example #22
Source File: NumberInput.tsx From react-native-jigsaw with MIT License | 5 votes |
NumberInput: FC<Props> = ({
onChangeText,
value,
defaultValue,
...props
}) => {
const [currentStringNumberValue, setCurrentStringNumberValue] = useState("0");
const formatValueToStringNumber = (valueToFormat?: number | string) => {
if (valueToFormat != null) {
if (isString(valueToFormat) && valueToFormat !== "") {
if (/^0[1-9]$/.test(valueToFormat)) {
return valueToFormat.slice(1);
} else if (/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/.test(valueToFormat)) {
return valueToFormat;
} else {
return currentStringNumberValue;
}
} else if (isNumber(valueToFormat) && !isNaN(valueToFormat)) {
return valueToFormat.toString();
}
}
return "0";
};
// set currentStringNumberValue as defaultValue prop if there is a differnce on first render only
useEffect(() => {
const defaultStringNumberValue = formatValueToStringNumber(defaultValue);
if (currentStringNumberValue !== defaultStringNumberValue) {
setCurrentStringNumberValue(defaultStringNumberValue);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const handleChangeText = (newValue: string) => {
const newStringNumberValue = formatValueToStringNumber(newValue);
const number = parseFloat(newStringNumberValue);
setCurrentStringNumberValue(newStringNumberValue);
onChangeText?.(number);
};
// run handleChangeText with value prop only when value prop changes (and first render to reset currentStringNumberValue)
useEffect(() => {
const nextStringNumberValue = formatValueToStringNumber(value);
if (currentStringNumberValue !== nextStringNumberValue) {
handleChangeText(nextStringNumberValue);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [value]);
return (
<TextInput
keyboardType="numeric"
value={currentStringNumberValue}
onChangeText={handleChangeText}
{...props}
/>
);
}
Example #23
Source File: pipeline-node.tsx From erda-ui with GNU Affero General Public License v3.0 | 5 votes |
private renderIcon() {
const { isType, status, result, costTimeSec } = this.props.item.data;
const operations = [];
// if (!starting) {
// 右侧图标:analysis config
// if (isType('dice')) {
// operations.push(this.getIconOperation('link', 'config-link', '配置中心'));
// }
// }
// 右侧跳转链接图标
if (status === 'Success') {
if (isType('it') || isType('ut')) {
operations.push(this.getIconOperation('link', 'test-link', i18n.t('test')));
}
// if (name === 'sonar') {
// operations.push(this.getIconOperation('link', 'sonar-link', '代码质量'));
// }
}
if (result) {
const { metadata } = result;
if (metadata != null) {
const runtimeID = metadata.find((a: any) => a.name === 'runtimeID');
if (runtimeID) {
operations.push(this.getIconOperation('link', 'link', i18n.t('Overview')));
}
const releaseID = metadata.find((a: any) => a.name === 'releaseID');
if (releaseID) {
operations.push(this.getIconOperation('link', 'release-link', i18n.t('dop:version details')));
}
const publisherID = metadata.find((a: any) => a.name === 'publisherID');
if (publisherID) {
operations.push(this.getIconOperation('link', 'publisher-link', i18n.t('publisher:publisher content')));
}
}
}
if (status === 'Running' || (executeStatus.includes(status) && isNumber(costTimeSec) && costTimeSec !== -1)) {
operations.push(this.getIconOperation('log', 'log', i18n.t('log')));
}
return operations.map((i: any, index: number) => (
<React.Fragment key={`operation-${String(index)}`}>{i}</React.Fragment>
));
}
Example #24
Source File: resubmit-report-popover.component.ts From fyle-mobile-app with MIT License | 5 votes |
filterCriticalViolations(etxn) {
return etxn.tx_policy_flag && isNumber(etxn.tx_policy_amount) && etxn.tx_policy_amount < 0.0001;
}
Example #25
Source File: InputMoney.tsx From gant-design with MIT License | 5 votes |
@compose(
withMoneyType,
withEdit(({ currency, money, format }) => {
if (!isNumber(money)) return null
const num = numeral(money).format(format)
return `${currency} ${num}`
}, "gantd-input-money-addonBefore"),
withProps(({ currency, onCurrencyChange, size }) => {
return ({
addonBefore: (
<Select dropdownClassName="gantd-input-money-addonBefore" className="gant-input-money-select" style={{ width: 75 }} value={currency}
size={size}
onChange={onCurrencyChange}>
{
symbols.map(type => <Select.Option key={type} value={type}>{type}</Select.Option>)
}
</Select>
),
})
}),
)
class InputMoney extends Component<any>{
state = {
value: undefined
}
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this)
}
onChange(v) {
const { reg, onMoneyChange } = this.props
let value = String(numeral(v).value()) // 通过numeral去掉非数字
const match = value.match(reg) // 最多两位小数
if (match && match[0]) {
value = match[0]
}
value = numeral(value).value() // 转化成数字
this.setState({
value
})
onMoneyChange(value)
}
render() {
const { setType, onEnter, wrapperRef, onValueChange, precision, format, reg, addonBefore, ...props } = this.props
const { value } = this.state
return (
<span className='gant-input-moeny'>
{addonBefore}
<InputNumber {...props} ref={wrapperRef} wrapperClassName={'gant-input-moeny-number'} isInner value={props.money || value} min={0} edit={EditStatus.EDIT} onPressEnter={onEnter} onChange={this.onChange} />
</span>
);
}
}
Example #26
Source File: is-dashboard-live-update.ts From js-client with MIT License | 5 votes |
isDashboardLiveUpdate = (value: unknown): value is DashboardLiveUpdate => {
try {
const d = <DashboardLiveUpdate>value;
return (d.enabled === true && isNumber(d.interval)) || (d.enabled === false && isNil(d.interval));
} catch {
return false;
}
}
Example #27
Source File: Col.tsx From gio-design with Apache License 2.0 | 5 votes |
Col = ({
component: Component = 'div',
prefixCls: customizePrefixCls,
children,
className,
style,
order,
offset,
span = 1,
}: React.PropsWithChildren<ColProps>) => {
const prefixCls = usePrefixCls('col', customizePrefixCls);
const { gutters } = useContext(RowContext);
const mergedStyle: React.CSSProperties = {
...(gutters[0] > 0
? {
paddingLeft: gutters[0] / 2,
paddingRight: gutters[0] / 2,
}
: {}),
...(gutters[1] > 0
? {
paddingTop: gutters[1] / 2,
paddingBottom: gutters[1] / 2,
}
: {}),
...style,
};
return (
<Component
className={classNames(prefixCls, className, `${prefixCls}-span-${span}`, {
[`${prefixCls}-order-${order}`]: isNumber(order),
[`${prefixCls}-offset-${offset}`]: isNumber(offset),
})}
style={mergedStyle}
>
{children}
</Component>
);
}
Example #28
Source File: Currency.tsx From leda with MIT License | 5 votes |
Currency = React.forwardRef((props: CurrencyProps, ref?: React.Ref<CurrencyRefCurrent>) => {
const {
children,
currencyCode = 'RUB',
currencySymbolRender,
placeholder: placeholderProp,
shouldTrimFraction,
precision,
value: valueProp,
wrapperRender,
...restProps
} = props;
const value = isNumber(valueProp) || isString(valueProp) ? valueProp : children;
const numericValue = getNumericValue(value);
const context = React.useContext(LedaContext);
const CurrencySymbol = useElement<CurrencyProps, {}, CurrencySymbolProps>(
'CurrencySymbol',
Span,
currencySymbolRender || context.renders[COMPONENTS_NAMESPACES.currency].currencySymbolRender,
props,
);
const Wrapper = useElement(
'Wrapper',
Span,
wrapperRender || context.renders[COMPONENTS_NAMESPACES.currency].wrapperRender,
props,
);
const formattedValue = formatNumber(CurrencySymbol, numericValue, precision, currencyCode, shouldTrimFraction);
const placeholder = isString(placeholderProp)
? placeholderProp
: '—';
return (
<Wrapper
ref={ref && ((component) => bindFunctionalRef(component, ref, component && {
wrapper: component.wrapper,
}))}
{...restProps}
>
{numericValue === null
? placeholder
: formattedValue}
</Wrapper>
);
}) as React.FC<CurrencyProps>
Example #29
Source File: WebGPUComputeModel.ts From GWebGPUEngine with MIT License | 4 votes |
public async init() {
const { computeStage } = await this.compileComputePipelineStageDescriptor(
this.context.shader!,
);
const buffers = this.context.uniforms.filter(
(uniform) => uniform.storageClass === STORAGE_CLASS.StorageBuffer,
);
const uniforms = this.context.uniforms.filter(
(uniform) => uniform.storageClass === STORAGE_CLASS.Uniform,
);
let bufferBindingIndex = uniforms.length ? 1 : 0;
this.bindGroupEntries = [];
if (bufferBindingIndex) {
let offset = 0;
// FIXME: 所有 uniform 合并成一个 buffer,固定使用 Float32Array 存储,确实会造成一些内存的浪费
// we use std140 layout @see https://www.khronos.org/opengl/wiki/Interface_Block_(GLSL)
const mergedUniformData: number[] = [];
uniforms.forEach((uniform) => {
if (isNumber(uniform.data)) {
this.uniformGPUBufferLayout.push({
name: uniform.name,
offset,
});
offset += 4;
mergedUniformData.push(uniform.data);
} else {
let originDataLength = uniform.data?.length || 1;
if (originDataLength === 3) {
// vec3 -> vec4
// @see http://ptgmedia.pearsoncmg.com/images/9780321552624/downloads/0321552628_AppL.pdf
originDataLength = 4;
uniform.data.push(0);
}
// 4 elements per block/line
const padding = (offset / 4) % 4;
if (padding > 0) {
const space = 4 - padding;
if (originDataLength > 1 && originDataLength <= space) {
if (originDataLength === 2) {
if (space === 3) {
offset += 4;
mergedUniformData.push(0);
}
mergedUniformData.push(...uniform.data);
this.uniformGPUBufferLayout.push({
name: uniform.name,
offset,
});
}
} else {
for (let i = 0; i < space; i++) {
offset += 4;
mergedUniformData.push(0);
}
mergedUniformData.push(...uniform.data);
this.uniformGPUBufferLayout.push({
name: uniform.name,
offset,
});
}
}
offset += 4 * originDataLength;
}
});
this.uniformBuffer = new WebGPUBuffer(this.engine, {
// TODO: 处理 Struct 和 boolean
// @ts-ignore
data:
mergedUniformData instanceof Array
? // @ts-ignore
new Float32Array(mergedUniformData)
: mergedUniformData,
usage:
WebGPUConstants.BufferUsage.Uniform |
WebGPUConstants.BufferUsage.CopyDst,
});
this.bindGroupEntries.push({
binding: 0,
resource: {
buffer: this.uniformBuffer.get(),
},
});
}
// create GPUBuffers for storeage buffers
buffers.forEach((buffer) => {
if (!isNil(buffer.data)) {
if (
buffer.type === AST_TOKEN_TYPES.Vector4FloatArray ||
buffer.type === AST_TOKEN_TYPES.FloatArray
) {
let gpuBuffer;
if (buffer.name === this.context.output.name) {
gpuBuffer = new WebGPUBuffer(this.engine, {
// @ts-ignore
data: isFinite(Number(buffer.data)) ? [buffer.data] : buffer.data,
usage:
WebGPUConstants.BufferUsage.Storage |
WebGPUConstants.BufferUsage.CopyDst |
WebGPUConstants.BufferUsage.CopySrc,
});
this.outputBuffer = gpuBuffer;
this.context.output = {
name: buffer.name,
// @ts-ignore
length: isFinite(Number(buffer.data)) ? 1 : buffer.data.length,
typedArrayConstructor: Float32Array,
gpuBuffer: gpuBuffer.get(),
};
} else {
if (buffer.isReferer) {
// @ts-ignore
if (buffer.data.model && buffer.data.model.outputBuffer) {
// @ts-ignore
gpuBuffer = (buffer.data.model as WebGPUComputeModel)
.outputBuffer;
} else {
// referred kernel haven't been executed
}
} else {
gpuBuffer = new WebGPUBuffer(this.engine, {
// @ts-ignore
data: isFinite(Number(buffer.data))
? [buffer.data]
: buffer.data,
usage:
WebGPUConstants.BufferUsage.Storage |
WebGPUConstants.BufferUsage.CopyDst |
WebGPUConstants.BufferUsage.CopySrc,
});
}
}
this.vertexBuffers[buffer.name] = gpuBuffer;
this.bindGroupEntries.push({
binding: bufferBindingIndex,
resource: {
name: buffer.name,
refer: gpuBuffer ? undefined : buffer.data,
buffer: gpuBuffer ? gpuBuffer.get() : undefined,
},
});
bufferBindingIndex++;
}
}
});
// create compute pipeline layout
this.computePipeline = this.engine.device.createComputePipeline({
computeStage,
});
console.log(this.bindGroupEntries);
this.bindGroup = this.engine.device.createBindGroup({
layout: this.computePipeline.getBindGroupLayout(0),
entries: this.bindGroupEntries,
});
}