Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Target 390]Serialize BufferAsset as CCON #15513

Draft
wants to merge 5 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions cocos/asset/assets/buffer-asset.jsb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ declare const jsb: any;
export type BufferAsset = JsbBufferAsset;
export const BufferAsset: typeof JsbBufferAsset = jsb.BufferAsset;

BufferAsset.prototype.buffer = function() {
if (!this._bufferLegacy) {
this._bufferLegacy = new Uint8Array(this.view);
}
return this._bufferLegacy;
};

cclegacy.BufferAsset = jsb.BufferAsset;

// handle meta data, it is generated automatically
Expand Down
54 changes: 28 additions & 26 deletions cocos/asset/assets/buffer-asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,49 +22,51 @@
THE SOFTWARE.
*/

import { ccclass, override } from 'cc.decorator';
import { assertIsNonNullable, cclegacy } from '../../core';
import { ccclass, override, serializable } from 'cc.decorator';
import { cclegacy } from '../../core';
import { Asset } from './asset';

/**
* @en
* `BufferAsset` is a kind of assets whose internal data is a section of memory buffer
* that you can access through the [[BufferAsset.buffer]] function.
* that you can access through `BufferAsset.view`.
* @zh
* `BufferAsset` 是一类资产,其内部数据是一段内存缓冲,你可以通过 [[BufferAsset.buffer]] 函数获取其内部数据
* `BufferAsset` 是一类资产,其内部数据是一段内存缓冲,你可以通过 `BufferAsset.view` 获取其内部数据
*/
@ccclass('cc.BufferAsset')
shrinktofit marked this conversation as resolved.
Show resolved Hide resolved
export class BufferAsset extends Asset {
private _buffer: ArrayBuffer | null = null;
/**
* @zh 缓冲数据的字节视图。
* @en Byte view of the buffered data.
*/
@serializable
public view = new Uint8Array();

/**
* @deprecated since v3.5.0, this is an engine private interface that will be removed in the future.
* @zh 首次调用将 **复制** 此时的`this.view`,并返回副本的 `ArrayBuffer`;该副本会在后续调用中直接返回。
* @en The first invocation on this method will **clone** `this.view` and returns `ArrayBuffer` of the copy.
* The copy will be directly returned in following invocations.
*
* @returns @en The `ArrayBuffer`. @zh `ArrayBuffer`。
*
* @deprecated @zh 自 3.9.0,此方法废弃,调用此方法将带来可观的性能开销;请转而使用 `this.view`。
* @en Since 3.9.0, this method is deprecated.
* Invocation on this method leads to significate cost. Use `this.view` instead.
*/
@override
get _nativeAsset (): ArrayBuffer | ArrayBufferView {
return this._buffer as ArrayBuffer;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overridden get/set _nativeAsset is removed. Will it break the compatibility?
The old get _nativeAsset return this._buffer, but now it returns this._file from its parent class Asset.

Copy link
Contributor Author

@shrinktofit shrinktofit Jul 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the method documented, this is an engine private interface and has been deprecated since v3.5.0 and is explicitly starts with an underscore. We can directly removed it in v3.9.0.

}
set _nativeAsset (bin: ArrayBufferView | ArrayBuffer) {
if (bin instanceof ArrayBuffer) {
this._buffer = bin;
} else {
this._buffer = bin.buffer;
public buffer (): ArrayBufferLike {
if (!this._bufferLegacy) {
this._bufferLegacy = new Uint8Array(this.view);
}
return this._bufferLegacy.buffer;
}

/**
* @zh 获取此资源中的缓冲数据。
* @en Get the ArrayBuffer data of this asset.
* @returns @en The ArrayBuffer. @zh 缓冲数据。
* This field is preserved here for compatibility purpose:
* prior to 3.9.0, `buffer()` returns `ArrayBuffer`.
* We can't directly returns `this.view` in `this.buffer()`
* since `this.view` does not view entire underlying buffer.
*/
public buffer (): ArrayBuffer {
assertIsNonNullable(this._buffer);
return this._buffer;
}

public validate (): boolean {
return !!this._buffer;
}
private _bufferLegacy: undefined | Uint8Array = undefined;
}

cclegacy.BufferAsset = BufferAsset;
15 changes: 15 additions & 0 deletions cocos/asset/assets/deprecated-3.9.0.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { replaceProperty } from '../../core/utils/x-deprecated';
import { BufferAsset } from './buffer-asset';

replaceProperty(
BufferAsset.prototype,
'BufferAsset',
[{
name: 'buffer',
newName: 'view',
target: BufferAsset.prototype,
targetName: 'BufferAsset',
customFunction: BufferAsset.prototype.buffer,
logTimes: 1,
}],
);
1 change: 1 addition & 0 deletions cocos/asset/assets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
*/

import './deprecation';
import './deprecated-3.9.0';

export { Asset } from './asset';
export { BufferAsset } from './buffer-asset';
Expand Down
3 changes: 1 addition & 2 deletions cocos/native-binding/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,7 @@ interface cc_BufferAsset_Context_Args {
}
export function patch_cc_BufferAsset(ctx: cc_BufferAsset_Context_Args, apply = defaultExec) {
const { BufferAsset } = { ...ctx };
const _nativeAssetDescriptor = Object.getOwnPropertyDescriptor(BufferAsset.prototype, '_nativeAsset');
apply(() => { $.override(BufferAsset.prototype, '_nativeAsset', _nativeAssetDescriptor); }, 'override', '_nativeAsset');
apply(() => { $.serializable(BufferAsset.prototype, 'view', () => { return new Uint8Array(); }); }, 'serializable', 'view');
apply(() => { $.ccclass('cc.BufferAsset')(BufferAsset); }, 'ccclass', null);
} // end of patch_cc_BufferAsset

Expand Down
7 changes: 0 additions & 7 deletions native/cocos/core/assets/BufferAsset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,5 @@

namespace cc {

ccstd::any BufferAsset::getNativeAsset() const {
return _buffer;
}

void BufferAsset::setNativeAsset(const ccstd::any &obj) {
_buffer = ccstd::any_cast<ArrayBuffer *>(obj);
}

} // namespace cc
14 changes: 4 additions & 10 deletions native/cocos/core/assets/BufferAsset.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

#pragma once

#include "core/ArrayBuffer.h"
#include "core/TypedArray.h"
#include "core/assets/Asset.h"

namespace cc {
Expand All @@ -34,17 +34,11 @@ class BufferAsset final : public Asset {
BufferAsset() = default;
~BufferAsset() override = default;

inline ArrayBuffer *getBuffer() const { return _buffer; }

inline void setNativeAssetForJS(ArrayBuffer *buffer) { _buffer = buffer; }
inline ArrayBuffer *getNativeAssetForJS() const { return _buffer; }

ccstd::any getNativeAsset() const override;
void setNativeAsset(const ccstd::any &obj) override;
bool validate() const override { return _buffer != nullptr; }
const Uint8Array &getView() { return _view; }
void setView(const Uint8Array &view) { _view = view; }

private:
ArrayBuffer::Ptr _buffer;
Uint8Array _view;

CC_DISALLOW_COPY_MOVE_ASSIGN(BufferAsset);
};
Expand Down
4 changes: 1 addition & 3 deletions native/tools/swig-config/assets.i
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,6 @@
%rename(_getBindposes) cc::Skeleton::getBindposes;
%rename(_setBindposes) cc::Skeleton::setBindposes;

%rename(buffer) cc::BufferAsset::getBuffer;



// ----- Module Macro Section ------
Expand Down Expand Up @@ -134,7 +132,7 @@
%attribute(cc::ImageAsset, cc::PixelFormat, format, getFormat, setFormat);
%attribute(cc::ImageAsset, ccstd::string&, url, getUrl, setUrl);

%attribute(cc::BufferAsset, cc::ArrayBuffer*, _nativeAsset, getNativeAssetForJS, setNativeAssetForJS);
%attribute(cc::BufferAsset, cc::Uint8Array&, view, getView, setView);

%attribute(cc::TextureBase, bool, isCompressed, isCompressed);
%attribute(cc::TextureBase, uint32_t, _width, getWidth, setWidth);
Expand Down
38 changes: 38 additions & 0 deletions tests/assets/buffer-asset.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { BufferAsset } from "../../exports/base";
import { captureWarns } from '../utils/log-capture';

test(`Deprecation warning`, () => {
const bufferAsset = new BufferAsset();

bufferAsset.view = new Uint8Array([3, 1, 8, 8]);

const warns = captureWarns();

// Deprecation message should be given at first invocation.
const bytesFirstInvocationResult = bufferAsset.buffer();
expect(warns.captured).toStrictEqual([
[`'%s' is deprecated, please use '%s' instead. `, `BufferAsset.buffer`, `BufferAsset.view`],
]);
warns.clear();

// The first invocation returns a copy of `.view`.
expect(bytesFirstInvocationResult).not.toBe(bufferAsset.view.buffer);
expect(new Uint8Array(bytesFirstInvocationResult)).toStrictEqual(bufferAsset.view);

// Repeatedly invocations on `buffer()` should return the same result.
const check = () => { expect(bufferAsset.buffer()).toBe(bytesFirstInvocationResult); };

check();

// The copy won't change event the `.view` has changed.
++bufferAsset.view[0];
check();
bufferAsset.view = new Uint8Array([7, 4, 5, 6]);
check();
// Verse vice.
{
const v = bufferAsset.view[0];
new Uint8Array(bufferAsset.buffer())[0] = v + 1;
expect(bufferAsset.view[0]).toBe(v);
}
});