source: 2014/24/EemeliK/Zombieland/Jypeli/Physics2DDotNet/Joints/Joint.cs @ 5974

Revision 5974, 6.9 KB checked in by empaheik, 4 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#if UseDouble
27using Scalar = System.Double;
28#else
29using Scalar = System.Single;
30#endif
31using System;
32using System.Collections.ObjectModel;
33
34
35namespace Physics2DDotNet.Joints
36{
37
38    /// <summary>
39    /// Describes a Connection between 2 objects.
40    /// </summary>
41#if !(WINDOWS_PHONE || XBOX)
42    [Serializable]
43#endif
44    public abstract class Joint : IJoint
45    {
46        /// <summary>
47        /// Raised when the Lifetime property has been Changed.
48        /// </summary>
49        public event EventHandler LifetimeChanged;
50        /// <summary>
51        /// Raised when the object is added to a Physics Engine.
52        /// </summary>
53        public event EventHandler Added;
54        /// <summary>
55        /// Raised when the object is Added to the engine but is not yet part of the update process.
56        /// </summary>
57        public event EventHandler Pending;
58        /// <summary>
59        /// Raised when the object is Removed from a Physics Engine.
60        /// </summary>
61        public event EventHandler<RemovedEventArgs> Removed;
62        object tag;
63        PhysicsEngine engine;
64        Lifespan lifetime;
65        bool isAdded;
66        internal bool isChecked;
67
68        protected Joint(Lifespan lifetime)
69        {
70            if (lifetime == null) { throw new ArgumentNullException("lifetime"); }
71            this.lifetime = lifetime;
72        }
73
74        /// <summary>
75        /// Gets if it has been added the the Engine's PendingQueue, but not yet added to the engine.
76        /// </summary>
77        public bool IsPending
78        {
79            get { return engine != null && !isAdded; }
80        }
81        /// <summary>
82        /// Gets and Sets a User defined object.
83        /// </summary>
84        public object Tag
85        {
86            get { return tag; }
87            set { tag = value; }
88        }
89        /// <summary>
90        /// Gets and Sets the LifeTime of the object. The object will be removed from the engine when it is Expired.
91        /// </summary>
92        public Lifespan Lifetime
93        {
94            get { return lifetime; }
95            set
96            {
97                if (value == null) { throw new ArgumentNullException("value"); }
98                if (this.lifetime != value)
99                {
100                    lifetime = value;
101                    if (LifetimeChanged != null) { LifetimeChanged(this, EventArgs.Empty); }
102                }
103            }
104        }
105        /// <summary>
106        /// Gets The PhysicsEngine the object is currently in. Null if it is in none.
107        /// </summary>
108        public PhysicsEngine Engine
109        {
110            get { return engine; }
111        }
112        /// <summary>
113        /// Gets if the object has been added to the engine.
114        /// </summary>
115        public bool IsAdded
116        {
117            get
118            {
119                return isAdded;
120            }
121        }
122        /// <summary>
123        /// Gets the bodies the Joint effects.
124        /// </summary>
125        public abstract ReadOnlyCollection<Body> Bodies { get;}
126
127        public abstract void CheckFrozen();
128
129        protected internal virtual void UpdateTime(TimeStep step)
130        {
131            lifetime.Update(step);
132        }
133        protected internal void BeforeAddCheckInternal(PhysicsEngine engine)
134        {
135            foreach (Body item in Bodies)
136            {
137                if (item.Engine != engine)
138                {
139                    throw new InvalidOperationException("All Bodies the Joint Effects Must Be added to the Same Engine Before the Joint is added.");
140                }
141            }
142            BeforeAddCheck(engine);
143        }
144        internal void OnPendingInternal(PhysicsEngine engine)
145        {
146            this.isChecked = false;
147            this.engine = engine;
148            OnPending(EventArgs.Empty);
149        }
150        internal void OnAddedInternal()
151        {
152            this.isAdded = true;
153            foreach (Body b in Bodies)
154            {
155                b.Removed += OnBodyRemoved;
156                b.AddJoint(this);
157            }
158            OnAdded(EventArgs.Empty);
159        }
160        internal void OnRemovedInternal()
161        {
162            bool isPending = IsPending;
163            foreach (Body b in Bodies)
164            {
165                b.IsFrozen = false;
166                b.idleCount = 0;
167                if (!isPending)
168                {
169                    b.RemoveJoint(this);
170                }
171                b.Removed -= OnBodyRemoved;
172            }
173            PhysicsEngine engine = this.engine;
174            bool wasPending = isPending;
175            this.isAdded = false;
176            this.engine = null;
177            OnRemoved(new RemovedEventArgs(engine, wasPending));
178        }
179        void OnBodyRemoved(object sender, EventArgs e)
180        {
181            this.lifetime.IsExpired = true;
182        }
183        protected virtual void OnPending(EventArgs e)
184        {
185            if (Pending != null) { Pending(this, e); }
186        }
187        protected virtual void OnAdded(EventArgs e)
188        {
189            if (Added != null) { Added(this, e); }
190        }
191        protected virtual void OnRemoved(RemovedEventArgs e)
192        {
193            foreach (Body b in Bodies)
194            {
195                b.IsFrozen = false;
196            }
197            if (Removed != null) { Removed(this, e); }
198        }
199        /// <summary>
200        /// Before the item is allowed to be added to pending this method is called to
201        /// throw any exceptions without corrupting the state of the Physics engine.
202        /// </summary>
203        /// <param name="engine">The engine the item is about to be added too.</param>
204        protected virtual void BeforeAddCheck(PhysicsEngine engine) { }
205
206
207
208    }
209}
Note: See TracBrowser for help on using the repository browser.