1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_particle_bridge.h"
16 
17 #include "frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
18 
19 namespace OHOS::Ace::NG {
20 constexpr int32_t DISTURBANCE_FIELD_SIZE = 10;
21 constexpr int32_t EMITTER_SIZE = 9;
22 constexpr int32_t STEP_0 = 0;
23 constexpr int32_t STEP_1 = 1;
24 constexpr int32_t STEP_2 = 2;
25 constexpr int32_t STEP_3 = 3;
26 constexpr int32_t STEP_4 = 4;
27 constexpr int32_t STEP_5 = 5;
28 constexpr int32_t STEP_6 = 6;
29 constexpr int32_t STEP_7 = 7;
30 constexpr int32_t STEP_8 = 8;
31 constexpr int32_t STEP_9 = 9;
32 
SetDisturbanceField(ArkUIRuntimeCallInfo * runtimeCallInfo)33 ArkUINativeModuleValue ParticleBridge::SetDisturbanceField(ArkUIRuntimeCallInfo* runtimeCallInfo)
34 {
35     EcmaVM* vm = runtimeCallInfo->GetVM();
36     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
37     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
38     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
39     Local<JSValueRef> jsValueRef = runtimeCallInfo->GetCallArgRef(1);
40     if (!jsValueRef->IsArray(vm)) {
41         return panda::JSValueRef::Undefined(vm);
42     }
43     auto array = panda::Local<panda::ArrayRef>(jsValueRef);
44     auto length = array->Length(vm);
45     std::vector<ArkUIInt32orFloat32> dataVector;
46     dataVector.resize(length);
47     for (uint32_t index = 0; index < length / DISTURBANCE_FIELD_SIZE; index++) {
48         Local<JSValueRef> strength = panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_0);
49         int32_t strengthValue = 0;
50         ArkTSUtils::ParseJsInteger(vm, strength, strengthValue);
51         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_0].f32 = static_cast<float>(strengthValue);
52         Local<JSValueRef> shape = panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_1);
53         int32_t shapeValue = 0;
54         ArkTSUtils::ParseJsInteger(vm, shape, shapeValue);
55         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_1].i32 = static_cast<int32_t>(shapeValue);
56         Local<JSValueRef> sizeWidth = panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_2);
57         int32_t sizeWidthValue = 0;
58         ArkTSUtils::ParseJsInteger(vm, sizeWidth, sizeWidthValue);
59         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_2].i32 = sizeWidthValue;
60         Local<JSValueRef> sizeHeight = panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_3);
61         int32_t sizeHeightValue = 0;
62         ArkTSUtils::ParseJsInteger(vm, sizeHeight, sizeHeightValue);
63         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_3].i32 = sizeHeightValue;
64         Local<JSValueRef> positionX = panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_4);
65         int32_t positionXValue = 0;
66         ArkTSUtils::ParseJsInteger(vm, positionX, positionXValue);
67         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_4].i32 = positionXValue;
68         Local<JSValueRef> positionY = panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_5);
69         int32_t positionYValue = 0;
70         ArkTSUtils::ParseJsInteger(vm, positionY, positionYValue);
71         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_5].i32 = positionYValue;
72         Local<JSValueRef> feather = panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_6);
73         int32_t featherValue = 0;
74         ArkTSUtils::ParseJsInteger(vm, feather, featherValue);
75         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_6].i32 = featherValue;
76         Local<JSValueRef> noiseScale = panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_7);
77         double noiseScaleValue = 1.0;
78         ArkTSUtils::ParseJsDouble(vm, noiseScale, noiseScaleValue);
79         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_7].f32 = static_cast<float>(noiseScaleValue);
80         Local<JSValueRef> noiseFrequency =
81             panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_8);
82         double noiseFrequencyValue = 1.0;
83         ArkTSUtils::ParseJsDouble(vm, noiseFrequency, noiseFrequencyValue);
84         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_8].f32 = static_cast<float>(noiseScaleValue);
85         Local<JSValueRef> noiseAmplitude =
86             panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_9);
87         double noiseAmplitudeValue = 1.0;
88         ArkTSUtils::ParseJsDouble(vm, noiseAmplitude, noiseAmplitudeValue);
89         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_9].f32 = static_cast<float>(noiseAmplitudeValue);
90     }
91     ArkUIInt32orFloat32* dataArray = dataVector.data();
92     GetArkUINodeModifiers()->getParticleModifier()->SetDisturbanceField(
93         nativeNode, dataArray, static_cast<ArkUI_Int32>(dataVector.size()));
94     return panda::JSValueRef::Undefined(vm);
95 }
96 
ResetDisturbanceField(ArkUIRuntimeCallInfo * runtimeCallInfo)97 ArkUINativeModuleValue ParticleBridge::ResetDisturbanceField(ArkUIRuntimeCallInfo* runtimeCallInfo)
98 {
99     EcmaVM* vm = runtimeCallInfo->GetVM();
100     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
101     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
102     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
103     GetArkUINodeModifiers()->getParticleModifier()->ResetDisturbanceField(nativeNode);
104     return panda::JSValueRef::Undefined(vm);
105 }
106 
SetEmitter(ArkUIRuntimeCallInfo * runtimeCallInfo)107 ArkUINativeModuleValue ParticleBridge::SetEmitter(ArkUIRuntimeCallInfo* runtimeCallInfo)
108 {
109     EcmaVM* vm = runtimeCallInfo->GetVM();
110     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
111     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
112     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
113     Local<JSValueRef> jsValueRef = runtimeCallInfo->GetCallArgRef(1);
114     if (!jsValueRef->IsArray(vm)) {
115         return panda::JSValueRef::Undefined(vm);
116     }
117     auto array = panda::Local<panda::ArrayRef>(jsValueRef);
118     auto length = array->Length(vm);
119     std::vector<ArkUIInt32orFloat32> dataVector;
120     dataVector.resize(length);
121 
122     for (uint32_t i = 0; i < length / EMITTER_SIZE; i++) {
123         Local<JSValueRef> index = panda::ArrayRef::GetValueAt(vm, array, i * EMITTER_SIZE + STEP_0);
124         int32_t indexValue = 0;
125         ArkTSUtils::ParseJsInteger(vm, index, indexValue);
126         dataVector[i * EMITTER_SIZE + STEP_0].i32 = indexValue;
127 
128         Local<JSValueRef> hasEmitRate = panda::ArrayRef::GetValueAt(vm, array, i * EMITTER_SIZE + STEP_1);
129         int32_t hasEmitRateValue = 0;
130         ArkTSUtils::ParseJsInteger(vm, hasEmitRate, hasEmitRateValue);
131         dataVector[i * EMITTER_SIZE + STEP_1].i32 = hasEmitRateValue;
132 
133         if (hasEmitRateValue == 1) { // has emitRate
134             Local<JSValueRef> emitRate = panda::ArrayRef::GetValueAt(vm, array, i * EMITTER_SIZE + STEP_2);
135             int32_t emitRateValue = 0;
136             ArkTSUtils::ParseJsInteger(vm, emitRate, emitRateValue);
137             dataVector[i * EMITTER_SIZE + STEP_2].i32 = emitRateValue;
138         }
139 
140         Local<JSValueRef> hasPosition = panda::ArrayRef::GetValueAt(vm, array, i * EMITTER_SIZE + STEP_3);
141         int32_t hasPositionValue = 0;
142         ArkTSUtils::ParseJsInteger(vm, hasPosition, hasPositionValue);
143         dataVector[i * EMITTER_SIZE + STEP_3].i32 = hasPositionValue;
144 
145         if (hasPositionValue == 1) { // has position
146             Local<JSValueRef> positionX = panda::ArrayRef::GetValueAt(vm, array, i * EMITTER_SIZE + STEP_4);
147             double positionXValue = 0.0;
148             ArkTSUtils::ParseJsDouble(vm, positionX, positionXValue);
149             dataVector[i * EMITTER_SIZE + STEP_4].f32 = static_cast<float>(positionXValue);
150             Local<JSValueRef> positionY = panda::ArrayRef::GetValueAt(vm, array, i * EMITTER_SIZE + STEP_5);
151             double positionYValue = 0.0;
152             ArkTSUtils::ParseJsDouble(vm, positionY, positionYValue);
153             dataVector[i * EMITTER_SIZE + STEP_5].f32 = static_cast<float>(positionYValue);
154         }
155 
156         Local<JSValueRef> hasSize = panda::ArrayRef::GetValueAt(vm, array, i * EMITTER_SIZE + STEP_6);
157         int32_t hasSizeValue = 0;
158         ArkTSUtils::ParseJsInteger(vm, hasSize, hasSizeValue);
159         dataVector[i * EMITTER_SIZE + STEP_6].i32 = hasSizeValue;
160 
161         if (hasSizeValue == 1) { // has size
162             Local<JSValueRef> sizeWidth = panda::ArrayRef::GetValueAt(vm, array, i * EMITTER_SIZE + STEP_7);
163             double sizeWidthValue = 0.0;
164             ArkTSUtils::ParseJsDouble(vm, sizeWidth, sizeWidthValue);
165             dataVector[i * EMITTER_SIZE + STEP_7].f32 = static_cast<float>(sizeWidthValue);
166             Local<JSValueRef> sizeHeight = panda::ArrayRef::GetValueAt(vm, array, i * EMITTER_SIZE + STEP_8);
167             double sizeHeightValue = 0.0;
168             ArkTSUtils::ParseJsDouble(vm, sizeHeight, sizeHeightValue);
169             dataVector[i * EMITTER_SIZE + STEP_8].f32 = static_cast<float>(sizeHeightValue);
170         }
171     }
172     GetArkUINodeModifiers()->getParticleModifier()->SetEmitter(
173         nativeNode, dataVector.data(), static_cast<ArkUI_Int32>(dataVector.size()));
174     return panda::JSValueRef::Undefined(vm);
175 }
176 
ResetEmitter(ArkUIRuntimeCallInfo * runtimeCallInfo)177 ArkUINativeModuleValue ParticleBridge::ResetEmitter(ArkUIRuntimeCallInfo* runtimeCallInfo)
178 {
179     EcmaVM* vm = runtimeCallInfo->GetVM();
180     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
181     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
182     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
183     GetArkUINodeModifiers()->getParticleModifier()->ResetEmitter(nativeNode);
184     return panda::JSValueRef::Undefined(vm);
185 }
186 } // namespace OHOS::Ace::NG