-
Notifications
You must be signed in to change notification settings - Fork 241
/
ParticleModifier.cs
175 lines (157 loc) · 6.72 KB
/
ParticleModifier.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/*
* Copyright(c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System.Reflection;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Tizen.NUI.ParticleSystem
{
/// <summary>
/// ParticleModifierInterface provides callbacks in order to define
/// how particles in the system should be modified
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public class ParticleModifierInterface
{
/// <summary>
/// Constructor
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public ParticleModifierInterface()
{
}
/// <summary>
/// Second constructor
/// </summary>
/// <remarks>
/// Second constructor should be overriden by the implementation.
/// It allows passing variable number of arguments for processing.
/// It is called immediately following the class constructor.
/// </remarks>
/// <param name="list">List of arguments</param>
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual void Construct(params object[] list)
{
}
/// <summary>
/// Updates the ParticleModifier.
/// </summary>
/// <remarks>
/// This callback is responsible for updating particles in the system.
///
/// This callback runs on the Update thread! It should avoid using NUI objects.
///
/// </remarks>
/// <param name="emitterProxy">Proxy to the ParticleEmitter object</param>
/// <param name="particleList">List of particles to be updated by the modifier</param>
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual void Update(ParticleEmitterProxy emitterProxy, List<Particle> particleList)
{
}
/// <summary>
/// ParticleEmitter proxy that can be accessed by the user implementation
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public ParticleEmitterProxy Emitter;
}
/// <summary>
/// Class represents particle modifier
/// </summary>
/// <remarks>
/// ParticleModifier modifies existing particles in the system.
/// Modifiers can be stacked (more than one can be added to the ParticleEmitter).
/// Output of one modifier becomes input for next modifier.
///
/// Modifier calls into the implementation of <see cref="ParticleModifierInterface"/> class.
///
/// </remarks>
/// <typeparam name="T">Class of interface that derives from <see cref="ParticleModifierInterface"/></typeparam>
[EditorBrowsable(EditorBrowsableState.Never)]
public partial class ParticleModifier<T> : BaseHandle where T : ParticleModifierInterface, new()
{
// static cache for modifiers (binding between native side and interfaces)
static ParticleInterfaceRegister<ParticleModifierInterface> gModifierInterfaceRegister = new ParticleInterfaceRegister<ParticleModifierInterface>();
/// <summary>
/// Dispose.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
protected override void Dispose(DisposeTypes type)
{
if (Disposed)
{
return;
}
if (HasBody())
{
gModifierInterfaceRegister.Remove(mInterface);
}
base.Dispose(type);
}
/// <summary>
/// Invoker for ParticleModifierInterface.Update()
/// </summary>
/// <param name="cPtr">Native pointer of ParticleModifier base object</param>
/// <param name="listPtr">C-style array of integers</param>
/// <param name="first">First particle to be modified (now always 0)</param>
/// <param name="count">Number of particles to be modified</param>
[EditorBrowsable(EditorBrowsableState.Never)]
static void OnUpdateInvoker(IntPtr cPtr, IntPtr listPtr, uint first, uint count)
{
if (count > 0)
{
T modifier = (cPtr == IntPtr.Zero) ? null : gModifierInterfaceRegister.Get(cPtr) as T;
var list = modifier?.Emitter.AcquireParticleList(listPtr, count);
modifier?.Update(modifier.Emitter, list);
modifier?.Emitter.ReleaseParticleList(list);
}
}
internal ParticleModifier(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
{
}
/// <summary>
/// Constructor of ParticleModifier
/// </summary>
/// <remarks>
/// ParticleModifier is a generic type that will call back into the given ParticleModifierInterface
/// instance.
/// The instance of T (derived from ParticleModifierInterface) is created internally and own by the
/// ParticleModifier.
/// The constructor takes variable number of arguments which is processed when called ParticleModifierInterface.Construct()
/// </remarks>
[EditorBrowsable(EditorBrowsableState.Never)]
public ParticleModifier(params object[] list) : this(Interop.ParticleModifier.New(mOnUpdateInvoker, out gRefObjectPtr), true)
{
// Create interface on the C# side (no direct connection with C++)
mInterface = new T();
mInterface.Construct(list);
// Register interface using base ptr
gModifierInterfaceRegister.Register(gRefObjectPtr, mInterface);
// Initialise native side for this interface
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
}
[EditorBrowsable(EditorBrowsableState.Never)]
internal void SetEmitter(ParticleEmitter emitter)
{
mInterface.Emitter = new ParticleEmitterProxy(emitter);
}
private static Interop.ParticleModifier.ParticleModifierUpdateInvokerType mOnUpdateInvoker = OnUpdateInvoker;
private ParticleModifierInterface mInterface = null;
private static IntPtr gRefObjectPtr;
}
}