• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 STEP_0 = 0;
22 constexpr int32_t STEP_1 = 1;
23 constexpr int32_t STEP_2 = 2;
24 constexpr int32_t STEP_3 = 3;
25 constexpr int32_t STEP_4 = 4;
26 constexpr int32_t STEP_5 = 5;
27 constexpr int32_t STEP_6 = 6;
28 constexpr int32_t STEP_7 = 7;
29 constexpr int32_t STEP_8 = 8;
30 constexpr int32_t STEP_9 = 9;
31 constexpr double DEFAULT_CENTER_VALUE = 0.5;
32 constexpr int32_t DEFAULT_ANNULUS_UNIT = static_cast<int32_t>(DimensionUnit::PERCENT);
33 constexpr double DEFAULT_START_ANGLE_VALUE = 0.0;
34 constexpr double DEFAULT_END_ANGLE_VALUE = 360.0;
35 
36 namespace {
ParseAnnulusRegionCenter(EcmaVM * vm,panda::Local<panda::FunctionRef> emitterPropertyObj,ArkEmitterPropertyOptions & emitterProperty)37 void ParseAnnulusRegionCenter(EcmaVM* vm, panda::Local<panda::FunctionRef> emitterPropertyObj,
38     ArkEmitterPropertyOptions& emitterProperty)
39 {
40     //parse annulusRegion center
41     auto isSetCenter = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "isSetCenter"));
42     int32_t hasCenterValue = 0;
43     ArkTSUtils::ParseJsInteger(vm, isSetCenter, hasCenterValue);
44     emitterProperty.isSetCenter = hasCenterValue;
45     if (hasCenterValue == 1) {
46         auto centerXValueJs = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "centerXValue"));
47         auto centerXUnitJs = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "centerXUnit"));
48         double centerXValue = DEFAULT_CENTER_VALUE;
49         int32_t centerXUnit = DEFAULT_ANNULUS_UNIT;
50         ArkTSUtils::ParseJsDouble(vm, centerXValueJs, centerXValue);
51         ArkTSUtils::ParseJsInteger(vm, centerXUnitJs, centerXUnit);
52         ArkUIDimensionType centerX;
53         centerX.value = centerXValue;
54         centerX.units = centerXUnit;
55         emitterProperty.centerX = centerX;
56 
57         auto centerYValueJs = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "centerYValue"));
58         auto centerYUnitJs = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "centerYUnit"));
59         double centerYValue = DEFAULT_CENTER_VALUE;
60         int32_t centerYUnit = DEFAULT_ANNULUS_UNIT;
61         ArkTSUtils::ParseJsDouble(vm, centerYValueJs, centerYValue);
62         ArkTSUtils::ParseJsInteger(vm, centerYUnitJs, centerYUnit);
63         ArkUIDimensionType centerY;
64         centerY.value = centerYValue;
65         centerY.units = centerYUnit;
66         emitterProperty.centerY = centerY;
67     }
68 }
69 
ParseAnnulusRegionRadius(EcmaVM * vm,panda::Local<panda::FunctionRef> emitterPropertyObj,ArkEmitterPropertyOptions & emitterProperty)70 void ParseAnnulusRegionRadius(EcmaVM* vm, panda::Local<panda::FunctionRef> emitterPropertyObj,
71     ArkEmitterPropertyOptions& emitterProperty)
72 {
73     //parse annulusRegion radius
74     auto isSetInnerRadius = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "isSetInnerRadius"));
75     int32_t hasInnerRadiusValue = 0;
76     ArkTSUtils::ParseJsInteger(vm, isSetInnerRadius, hasInnerRadiusValue);
77     emitterProperty.isSetInnerRadius = hasInnerRadiusValue;
78     if (hasInnerRadiusValue == 1) {
79         auto innerRadiusValueJs = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "innerRadiusValue"));
80         auto innerRadiusXUnitJs = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "innerRadiusUnit"));
81         double innerRadiusValue = 0.0;
82         int32_t innerRadiusXUnit = 0;
83         ArkTSUtils::ParseJsDouble(vm, innerRadiusValueJs, innerRadiusValue);
84         ArkTSUtils::ParseJsInteger(vm, innerRadiusXUnitJs, innerRadiusXUnit);
85         ArkUIDimensionType innerRadius;
86         innerRadius.value = innerRadiusValue;
87         innerRadius.units = innerRadiusXUnit;
88         emitterProperty.innerRadius = innerRadius;
89     }
90 
91     auto isSetOuterRadius = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "isSetOuterRadius"));
92     int32_t hasOuterRadiusValue = 0;
93     ArkTSUtils::ParseJsInteger(vm, isSetOuterRadius, hasOuterRadiusValue);
94     emitterProperty.isSetOuterRadius = hasOuterRadiusValue;
95     if (hasOuterRadiusValue == 1) {
96         auto outerRadiusValueJs = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "outerRadiusValue"));
97         auto outerRadiusXUnitJs = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "outerRadiusUnit"));
98         double outerRadiusValue = 0.0;
99         int32_t outerRadiusXUnit = 0;
100         ArkTSUtils::ParseJsDouble(vm, outerRadiusValueJs, outerRadiusValue);
101         ArkTSUtils::ParseJsInteger(vm, outerRadiusXUnitJs, outerRadiusXUnit);
102         ArkUIDimensionType outerRadius;
103         outerRadius.value = outerRadiusValue;
104         outerRadius.units = outerRadiusXUnit;
105         emitterProperty.outerRadius = outerRadius;
106     }
107 }
108 
ParseAnnulusRegionAngle(EcmaVM * vm,panda::Local<panda::FunctionRef> emitterPropertyObj,ArkEmitterPropertyOptions & emitterProperty)109 void ParseAnnulusRegionAngle(EcmaVM* vm, panda::Local<panda::FunctionRef> emitterPropertyObj,
110     ArkEmitterPropertyOptions& emitterProperty)
111 {
112     //parse annulusRegion angle
113     auto isSetStartAngle = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "isSetStartAngle"));
114     int32_t hasStartAngleValue = 0;
115     ArkTSUtils::ParseJsInteger(vm, isSetStartAngle, hasStartAngleValue);
116     emitterProperty.isSetStartAngle = hasStartAngleValue;
117     if (hasStartAngleValue == 1) {
118         auto startAngle = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "startAngle"));
119         double startAngleValue = DEFAULT_START_ANGLE_VALUE;
120         ArkTSUtils::ParseJsDouble(vm, startAngle, startAngleValue);
121         emitterProperty.startAngle = startAngleValue;
122     }
123 
124     auto isSetEndAngle = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "isSetEndAngle"));
125     int32_t hasEndAngleValue = 0;
126     ArkTSUtils::ParseJsInteger(vm, isSetEndAngle, hasEndAngleValue);
127     emitterProperty.isSetEndAngle = hasEndAngleValue;
128     if (hasEndAngleValue == 1) {
129         auto endAngle = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "endAngle"));
130         double endAngleValue = DEFAULT_END_ANGLE_VALUE;
131         ArkTSUtils::ParseJsDouble(vm, endAngle, endAngleValue);
132         emitterProperty.endAngle = endAngleValue;
133     }
134 }
135 
ParseEmitterAnnulusRegion(EcmaVM * vm,panda::Local<panda::FunctionRef> emitterPropertyObj,ArkEmitterPropertyOptions & emitterProperty)136 void ParseEmitterAnnulusRegion(EcmaVM* vm, panda::Local<panda::FunctionRef> emitterPropertyObj,
137     ArkEmitterPropertyOptions& emitterProperty)
138 {
139     //parse annulusRegion
140     auto isSetAnnulusRegion = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "isSetAnnulusRegion"));
141     int32_t hasAnnulusRegionValue = 0;
142     ArkTSUtils::ParseJsInteger(vm, isSetAnnulusRegion, hasAnnulusRegionValue);
143     emitterProperty.isSetAnnulusRegion = hasAnnulusRegionValue;
144     if (hasAnnulusRegionValue == 1) {
145         ParseAnnulusRegionCenter(vm, emitterPropertyObj, emitterProperty);
146         ParseAnnulusRegionRadius(vm, emitterPropertyObj, emitterProperty);
147         ParseAnnulusRegionAngle(vm, emitterPropertyObj, emitterProperty);
148     }
149 }
150 
ParseEmitterPositionAndSize(EcmaVM * vm,panda::Local<panda::FunctionRef> emitterPropertyObj,ArkEmitterPropertyOptions & emitterProperty)151 void ParseEmitterPositionAndSize(EcmaVM* vm, panda::Local<panda::FunctionRef> emitterPropertyObj,
152     ArkEmitterPropertyOptions& emitterProperty)
153 {
154     //parse position
155     auto isSetPosition = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "isSetPosition"));
156     int32_t hasPositionValue = 0;
157     ArkTSUtils::ParseJsInteger(vm, isSetPosition, hasPositionValue);
158     emitterProperty.isSetPosition = hasPositionValue;
159     if (hasPositionValue == 1) {
160         auto positionX = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "positionX"));
161         double positionXValue = 0.0;
162         ArkTSUtils::ParseJsDouble(vm, positionX, positionXValue);
163         emitterProperty.positionX = positionXValue;
164         auto positionY = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "positionY"));
165         double positionYValue = 0.0;
166         ArkTSUtils::ParseJsDouble(vm, positionY, positionYValue);
167         emitterProperty.positionY = positionYValue;
168     }
169 
170     //parse size
171     auto isSetSize = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "isSetSize"));
172     int32_t hasSizeValue = 0;
173     ArkTSUtils::ParseJsInteger(vm, isSetSize, hasSizeValue);
174     emitterProperty.isSetSize = hasSizeValue;
175     if (hasSizeValue == 1) {
176         auto sizeWidth = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "sizeWidth"));
177         double sizeWidthValue = 0.0;
178         ArkTSUtils::ParseJsDouble(vm, sizeWidth, sizeWidthValue);
179         emitterProperty.sizeWidth = sizeWidthValue;
180         auto sizeHeight = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "sizeHeight"));
181         double sizeHeightValue = 0.0;
182         ArkTSUtils::ParseJsDouble(vm, sizeHeight, sizeHeightValue);
183         emitterProperty.sizeHeight = sizeHeightValue;
184     }
185 }
186 }
187 
SetDisturbanceField(ArkUIRuntimeCallInfo * runtimeCallInfo)188 ArkUINativeModuleValue ParticleBridge::SetDisturbanceField(ArkUIRuntimeCallInfo* runtimeCallInfo)
189 {
190     EcmaVM* vm = runtimeCallInfo->GetVM();
191     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
192     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
193     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
194     Local<JSValueRef> jsValueRef = runtimeCallInfo->GetCallArgRef(1);
195     if (!jsValueRef->IsArray(vm)) {
196         return panda::JSValueRef::Undefined(vm);
197     }
198     auto array = panda::Local<panda::ArrayRef>(jsValueRef);
199     auto length = array->Length(vm);
200     std::vector<ArkUIInt32orFloat32> dataVector;
201     dataVector.resize(length);
202     for (uint32_t index = 0; index < length / DISTURBANCE_FIELD_SIZE; index++) {
203         Local<JSValueRef> strength = panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_0);
204         int32_t strengthValue = 0;
205         ArkTSUtils::ParseJsInteger(vm, strength, strengthValue);
206         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_0].f32 = static_cast<float>(strengthValue);
207         Local<JSValueRef> shape = panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_1);
208         int32_t shapeValue = 0;
209         ArkTSUtils::ParseJsInteger(vm, shape, shapeValue);
210         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_1].i32 = static_cast<int32_t>(shapeValue);
211         Local<JSValueRef> sizeWidth = panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_2);
212         int32_t sizeWidthValue = 0;
213         ArkTSUtils::ParseJsInteger(vm, sizeWidth, sizeWidthValue);
214         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_2].i32 = sizeWidthValue;
215         Local<JSValueRef> sizeHeight = panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_3);
216         int32_t sizeHeightValue = 0;
217         ArkTSUtils::ParseJsInteger(vm, sizeHeight, sizeHeightValue);
218         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_3].i32 = sizeHeightValue;
219         Local<JSValueRef> positionX = panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_4);
220         int32_t positionXValue = 0;
221         ArkTSUtils::ParseJsInteger(vm, positionX, positionXValue);
222         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_4].i32 = positionXValue;
223         Local<JSValueRef> positionY = panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_5);
224         int32_t positionYValue = 0;
225         ArkTSUtils::ParseJsInteger(vm, positionY, positionYValue);
226         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_5].i32 = positionYValue;
227         Local<JSValueRef> feather = panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_6);
228         int32_t featherValue = 0;
229         ArkTSUtils::ParseJsInteger(vm, feather, featherValue);
230         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_6].i32 = featherValue;
231         Local<JSValueRef> noiseScale = panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_7);
232         double noiseScaleValue = 1.0;
233         ArkTSUtils::ParseJsDouble(vm, noiseScale, noiseScaleValue);
234         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_7].f32 = static_cast<float>(noiseScaleValue);
235         Local<JSValueRef> noiseFrequency =
236             panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_8);
237         double noiseFrequencyValue = 1.0;
238         ArkTSUtils::ParseJsDouble(vm, noiseFrequency, noiseFrequencyValue);
239         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_8].f32 = static_cast<float>(noiseScaleValue);
240         Local<JSValueRef> noiseAmplitude =
241             panda::ArrayRef::GetValueAt(vm, array, index * DISTURBANCE_FIELD_SIZE + STEP_9);
242         double noiseAmplitudeValue = 1.0;
243         ArkTSUtils::ParseJsDouble(vm, noiseAmplitude, noiseAmplitudeValue);
244         dataVector[index * DISTURBANCE_FIELD_SIZE + STEP_9].f32 = static_cast<float>(noiseAmplitudeValue);
245     }
246     ArkUIInt32orFloat32* dataArray = dataVector.data();
247     GetArkUINodeModifiers()->getParticleModifier()->SetDisturbanceField(
248         nativeNode, dataArray, static_cast<ArkUI_Int32>(dataVector.size()));
249     return panda::JSValueRef::Undefined(vm);
250 }
251 
ResetDisturbanceField(ArkUIRuntimeCallInfo * runtimeCallInfo)252 ArkUINativeModuleValue ParticleBridge::ResetDisturbanceField(ArkUIRuntimeCallInfo* runtimeCallInfo)
253 {
254     EcmaVM* vm = runtimeCallInfo->GetVM();
255     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
256     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
257     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
258     GetArkUINodeModifiers()->getParticleModifier()->ResetDisturbanceField(nativeNode);
259     return panda::JSValueRef::Undefined(vm);
260 }
261 
SetEmitter(ArkUIRuntimeCallInfo * runtimeCallInfo)262 ArkUINativeModuleValue ParticleBridge::SetEmitter(ArkUIRuntimeCallInfo* runtimeCallInfo)
263 {
264     EcmaVM* vm = runtimeCallInfo->GetVM();
265     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
266     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
267     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
268     Local<JSValueRef> jsValueRef = runtimeCallInfo->GetCallArgRef(1);
269     if (!jsValueRef->IsArray(vm)) {
270         return panda::JSValueRef::Undefined(vm);
271     }
272     auto array = panda::Local<panda::ArrayRef>(jsValueRef);
273     auto length = array->Length(vm);
274     std::vector<ArkEmitterPropertyOptions> dataVector;
275     dataVector.resize(length);
276 
277     for (uint32_t i = 0; i < length; i++) {
278         ArkEmitterPropertyOptions emitterProperty;
279         Local<JSValueRef> emitterPropertyValue = panda::ArrayRef::GetValueAt(vm, array, i);
280         if (emitterPropertyValue->IsObject(vm)) {
281             auto emitterPropertyObj = emitterPropertyValue->ToObject(vm);
282 
283             //parse index
284             auto index = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "index"));
285             int32_t indexValue = 0;
286             ArkTSUtils::ParseJsInteger(vm, index, indexValue);
287             emitterProperty.index = indexValue;
288 
289             //parse emitRate
290             auto isSetEmitRate = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "isSetEmitRate"));
291             int32_t hasEmitRateValue = 0;
292             ArkTSUtils::ParseJsInteger(vm, isSetEmitRate, hasEmitRateValue);
293             emitterProperty.isSetEmitRate = hasEmitRateValue;
294             if (hasEmitRateValue == 1) {
295                 auto emitRate = emitterPropertyObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "emitRate"));
296                 int32_t emitRateValue = 0;
297                 ArkTSUtils::ParseJsInteger(vm, emitRate, emitRateValue);
298                 emitterProperty.emitRate = emitRateValue;
299             }
300             ParseEmitterPositionAndSize(vm, emitterPropertyObj, emitterProperty);
301             ParseEmitterAnnulusRegion(vm, emitterPropertyObj, emitterProperty);
302         }
303         dataVector.emplace_back(emitterProperty);
304     }
305     GetArkUINodeModifiers()->getParticleModifier()->SetEmitter(
306         nativeNode, dataVector.data(), static_cast<ArkUI_Int32>(dataVector.size()));
307     return panda::JSValueRef::Undefined(vm);
308 }
309 
ResetEmitter(ArkUIRuntimeCallInfo * runtimeCallInfo)310 ArkUINativeModuleValue ParticleBridge::ResetEmitter(ArkUIRuntimeCallInfo* runtimeCallInfo)
311 {
312     EcmaVM* vm = runtimeCallInfo->GetVM();
313     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
314     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
315     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
316     GetArkUINodeModifiers()->getParticleModifier()->ResetEmitter(nativeNode);
317     return panda::JSValueRef::Undefined(vm);
318 }
319 } // namespace OHOS::Ace::NG