source: 2013/30/MiskaK/MW2(My Warfare 2)/Paranneltu Jypeli/Storage/FileManager/HTTP.cs @ 4507

Revision 4507, 7.6 KB checked in by anlakane, 6 years ago (diff)

Talletus.

Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.IO;
5using System.Net;
6
7namespace Jypeli
8{
9    public abstract partial class FileManager : Updatable
10    {
11        public class AsyncOperation
12        {
13            public HttpWebRequest Request;
14            public IAsyncResult Result;
15            public TimeSpan Lifetime;
16            public Action<StorageFile> Callback;
17
18            public bool IsCompleted
19            {
20                get { return Result == null ? true : Result.IsCompleted; }
21            }
22
23            public AsyncOperation( HttpWebRequest req, Action<StorageFile> callback )
24            {
25                this.Request = req;
26                this.Callback = callback;
27                this.Lifetime = TimeSpan.FromSeconds( 15 );
28            }
29
30            public AsyncOperation( HttpWebRequest req, Action<StorageFile> callback, TimeSpan timeout )
31            {
32                this.Request = req;
33                this.Callback = callback;
34                this.Lifetime = timeout;
35            }
36        }
37
38        private class AsyncTrigger
39        {
40            public List<AsyncOperation> ops;
41            public Action onCompleted;
42            public int triggered = 0;
43            public int failed = 0;
44
45            public AsyncTrigger( List<AsyncOperation> operations, Action endAction )
46            {
47                this.ops = operations;
48                this.onCompleted = endAction;
49            }
50
51            public AsyncTrigger( List<AsyncOperation> operations, TimeSpan timeout, Action endAction )
52            {
53                this.ops = operations;
54                this.onCompleted = endAction;
55                foreach ( var op in ops ) op.Lifetime = timeout;
56            }
57        }
58       
59        SynchronousList<AsyncTrigger> triggers = new SynchronousList<AsyncTrigger>();
60
61        public bool IsUpdated
62        {
63            get { return triggers.Count > 0; }
64        }
65
66        public void Update( Time time )
67        {
68            triggers.Update( time );
69
70            foreach ( var trig in triggers )
71            {
72                foreach ( var op in trig.ops.FindAll( o => !o.IsCompleted ) )
73                {
74                    op.Lifetime -= time.SinceLastUpdate;
75
76                    if ( op.Lifetime.TotalSeconds <= 0 )
77                    {
78                        //Game.Instance.MessageDisplay.Add( "!!ABORT" );
79                        op.Request.Abort();
80                        trig.failed++;
81                    }
82                }
83
84                if ( trig.triggered + trig.failed >= trig.ops.Count )
85                {
86                    triggers.Remove( trig );
87                    trig.onCompleted();
88                }
89            }
90        }
91
92        /// <summary>
93        /// Avaa tiedoston (lukua varten) ja tekee sillä jotain.
94        /// </summary>
95        /// <param name="fileName">Tiedoston nimi</param>
96        /// <param name="callback">Mitä tehdään (aliohjelman nimi)</param>
97        /// <example>
98        /// {
99        ///    DoWith( "kuva.png", AsetaKuva );
100        /// }
101        ///
102        /// void AsetaKuva( StorageFile kuva )
103        /// {
104        ///    olio.Image = new Image( kuva );
105        /// }
106        /// </example>
107        public AsyncOperation DoWith( string fileName, Action<StorageFile> callback )
108        {
109            using ( var f = Open( fileName, false ) )
110            {
111                callback( f );
112            }
113
114            return new AsyncOperation( null, callback );
115        }
116
117        /// <summary>
118        /// Avaa tiedoston netistä (lukua varten) ja tekee sillä jotain.
119        /// </summary>
120        /// <param name="url">Nettiosoite</param>
121        /// <param name="callback">Mitä tehdään (aliohjelman nimi)</param>
122        /// <example>
123        /// {
124        ///    DoWith( "http://www.google.fi/images/srpr/logo3w.png", AsetaKuva );
125        /// }
126        ///
127        /// void AsetaKuva( StorageFile kuva )
128        /// {
129        ///    olio.Image = new Image( kuva );
130        /// }
131        /// </example>
132        public AsyncOperation DoWithURL( string url, Action<StorageFile> callback )
133        {
134            HttpWebRequest request = (HttpWebRequest)WebRequest.Create( url );
135            AsyncOperation op = new AsyncOperation( request, callback );
136            IAsyncResult result = request.BeginGetResponse( DoWithCallback, op );
137            op.Result = result;
138            return op;
139        }
140
141        /// <summary>
142        /// Avaa tiedoston netistä (lukua varten) ja tekee sillä jotain.
143        /// </summary>
144        /// <param name="url">Nettiosoite</param>
145        /// <param name="callback">Mitä tehdään (aliohjelman nimi)</param>
146        /// <example>
147        /// {
148        ///    DoWith( "http://www.google.fi/images/srpr/logo3w.png", AsetaKuva );
149        /// }
150        ///
151        /// void AsetaKuva( StorageFile kuva )
152        /// {
153        ///    olio.Image = new Image( kuva );
154        /// }
155        /// </example>
156        public AsyncOperation DoWithURL( string url, TimeSpan timeout, Action<StorageFile> callback )
157        {
158            HttpWebRequest request = (HttpWebRequest)WebRequest.Create( url );
159            AsyncOperation op = new AsyncOperation( request, callback, timeout );
160            IAsyncResult result = request.BeginGetResponse( DoWithCallback, op );
161            op.Result = result;
162            return op;
163        }
164
165        private void DoWithCallback(IAsyncResult ar)
166        {
167            try
168            {
169                AsyncOperation op = (AsyncOperation)ar.AsyncState;
170                WebResponse response = op.Request.EndGetResponse( ar );
171                Stream resStream = response.GetResponseStream();
172                MemoryStream memStream = new MemoryStream();
173                resStream.CopyStreamTo( memStream );
174                resStream.Close();
175                response.Close();
176
177                memStream.Seek( 0, SeekOrigin.Begin );
178                op.Callback( new StorageFile( op.Request.RequestUri.AbsoluteUri, memStream ) );
179                memStream.Close();
180
181                foreach ( var trig in triggers.FindAll( t => t.ops.Any( o => o.Result == ar ) ) )
182                    trig.triggered++;
183
184            }
185            catch ( WebException we )
186            {
187                // Return if aborted
188                return;
189            }
190        }
191
192        /// <summary>
193        /// Laukaisee aliohjelman kun annetut operaatiot on suoritettu.
194        /// </summary>
195        /// <param name="callback">Aliohjelma</param>
196        /// <param name="actions">Operaatiot</param>
197        public void TriggerOnComplete( Action callback, params AsyncOperation[] actions )
198        {
199            triggers.Add( new AsyncTrigger( actions.ToList().FindAll( o => !o.IsCompleted ), callback ) );
200
201#if JYPELI
202            triggers.Update( Game.Time );
203#else
204            triggers.Update( Time.Zero );
205#endif
206        }
207
208        /// <summary>
209        /// Laukaisee aliohjelman kun annetut operaatiot on suoritettu.
210        /// </summary>
211        /// <param name="callback">Aliohjelma</param>
212        /// <param name="timeout">Kuinka pitkään odotetaan yksittäistä operaatiota ennen kuin luovutetaan</param>
213        /// <param name="actions">Operaatiot</param>
214        public void TriggerOnComplete( Action callback, TimeSpan timeout, params AsyncOperation[] actions )
215        {
216            triggers.Add( new AsyncTrigger( actions.ToList().FindAll( o => !o.IsCompleted ), timeout, callback ) );
217#if JYPELI
218            triggers.Update( Game.Time );
219#else
220            triggers.Update( Time.Zero );
221#endif
222        }
223    }
224}
Note: See TracBrowser for help on using the repository browser.