source: 2014/24/EemeliK/Zombieland/Jypeli/Physics2DDotNet/PhysicsLogics/PhysicsLogic.cs @ 5974

Revision 5974, 7.6 KB checked in by empaheik, 5 years ago (diff)
Line 
1#region MIT License
2/*
3 * Copyright (c) 2005-2008 Jonathan Mark Porter. http://physics2d.googlepages.com/
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights to
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 * the Software, and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22#endregion
23
24
25
26
27#if UseDouble
28using Scalar = System.Double;
29#else
30using Scalar = System.Single;
31#endif
32using System;
33using System.Collections.Generic;
34using System.Collections.ObjectModel;
35
36namespace Physics2DDotNet.PhysicsLogics
37{
38    /// <summary>
39    /// A physics logic is a way for the engine to effect object within the Update call.
40    /// Gravity is a Example of a PhysicsLogic.
41    /// </summary>
42#if !(WINDOWS_PHONE || XBOX)
43    [Serializable]
44#endif
45    public abstract class PhysicsLogic : IPhysicsEntity
46    {
47        #region static
48        private static ReadOnlyCollection<Body> none = new ReadOnlyCollection<Body>(new Body[0]);
49        protected static Lifespan GetLifeTime(Body body)
50        {
51            if (body == null) { throw new ArgumentNullException("body"); }
52            return body.Lifetime;
53        }
54        #endregion
55        #region events
56        /// <summary>
57        /// Raised when the Lifetime property has been Changed.
58        /// </summary>
59        public event EventHandler LifetimeChanged;
60        /// <summary>
61        /// Raised when the object is added to a Physics Engine.
62        /// </summary>
63        public event EventHandler Added;
64        /// <summary>
65        /// Raised when the object is Added to the engine but is not yet part of the update process.
66        /// </summary>
67        public event EventHandler Pending;
68        /// <summary>
69        /// Raised when the object is Removed from a Physics Engine.
70        /// </summary>
71        public event EventHandler<RemovedEventArgs> Removed; 
72        #endregion
73        #region fields
74        private int order;
75        private Lifespan lifetime;
76        private PhysicsEngine engine;
77        private object tag;
78        private bool isAdded;
79        internal bool isChecked; 
80        #endregion
81        #region constructors
82        protected PhysicsLogic(Lifespan lifetime)
83        {
84            if (lifetime == null) { throw new ArgumentNullException("lifetime"); }
85            this.lifetime = lifetime;
86        }
87        #endregion
88        #region properties
89        public virtual ReadOnlyCollection<Body> LogicBodies
90        {
91            get { return none; }
92        }
93        /// <summary>
94        /// Gets if it has been added the the Engine's PendingQueue, but not yet added to the engine.
95        /// </summary>
96        public bool IsPending
97        {
98            get { return engine != null && !isAdded; }
99        }
100        /// <summary>
101        /// Gets if the object has been added to the engine.
102        /// </summary>
103        public bool IsAdded
104        {
105            get { return isAdded; }
106        }
107        /// <summary>
108        /// Gets The PhysicsEngine the object is currently in. Null if it is in none.
109        /// </summary>
110        public PhysicsEngine Engine
111        {
112            get { return engine; }
113        }
114        /// <summary>
115        /// Gets and Sets a User defined object.
116        /// </summary>
117        public object Tag
118        {
119            get { return tag; }
120            set { tag = value; }
121        }
122        /// <summary>
123        /// Gets and Sets the LifeTime of the object. The object will be removed from the engine when it is Expired.
124        /// </summary>
125        public Lifespan Lifetime
126        {
127            get
128            {
129                return lifetime;
130            }
131            set
132            {
133                if (value == null) { throw new ArgumentNullException("value"); }
134                if (this.lifetime != value)
135                {
136                    lifetime = value;
137                    if (LifetimeChanged != null) { LifetimeChanged(this, EventArgs.Empty); }
138                }
139            }
140        }
141
142        protected List<Body> Bodies
143        {
144            get
145            {
146                return engine.bodies;
147            }
148        }
149        /// <summary>
150        /// Get and Sets The order number of when it will be ran.
151        /// All Logics with a higher order will run after this one and all logics
152        /// with a lower order number will be ran before this one.
153        /// </summary>
154        public int Order
155        {
156            get { return order; }
157            set
158            {
159                if (order != value)
160                {
161                    order = value;
162                    if (engine != null)
163                    {
164                        engine.logicsNeedSorting = true;
165                    }
166                }
167            }
168        } 
169        #endregion
170        #region methods
171
172        protected internal abstract void RunLogic(TimeStep step);
173
174        /// <summary>
175        /// Before the item is allowed to be added to pending this method is called to
176        /// throw any exceptions without corrupting the state of the Physics engine.
177        /// </summary>
178        /// <param name="engine">The engine the item is about to be added too.</param>
179        protected internal virtual void BeforeAddCheck(PhysicsEngine engine) { }
180        internal void OnPendingInternal(PhysicsEngine engine)
181        {
182            this.isChecked = true;
183            this.engine = engine;
184            OnPending(EventArgs.Empty);
185        }
186        internal void OnAddedInternal()
187        {
188            this.isAdded = true;
189            AddBodyRange(engine.bodies);
190            OnAdded(EventArgs.Empty);
191        }
192        internal void OnRemovedInternal()
193        {
194            Clear();
195            bool wasPending = this.IsPending;
196            PhysicsEngine engine = this.engine;
197            this.isAdded = false;
198            this.engine = null;
199            OnRemoved(new RemovedEventArgs(engine, wasPending));
200        }
201        protected virtual void OnPending(EventArgs e)
202        {
203            if (Pending != null) { Pending(this, e); }
204        }
205        protected virtual void OnAdded(EventArgs e)
206        {
207            if (Added != null) { Added(this, e); }
208        }
209        protected virtual void OnRemoved(RemovedEventArgs e)
210        {
211            if (Removed != null) { Removed(this, e); }
212        }
213        protected internal virtual void UpdateTime(TimeStep step)
214        {
215            this.lifetime.Update(step);
216        }
217
218        protected internal virtual void AddBodyRange(List<Body> collection) { }
219        protected internal virtual void RemoveExpiredBodies() { }
220        protected internal virtual void Clear() { } 
221        #endregion
222    }
223}
Note: See TracBrowser for help on using the repository browser.