Jump to content
Xtreme .Net Talk

snarfblam

Leaders
  • Posts

    2156
  • Joined

  • Last visited

  • Days Won

    2

Everything posted by snarfblam

  1. Is there a reason why you are creating a reference device? I can't how this could cause a problem, but it seems unusual. The problem might be related to the fact that you are creating the device before your form creates its handle. Try calling the InitializeDevice method from the OnLoad event method rather than the constructor.
  2. SleepingTroll, this is GDI+, not DirectX. It's impossible to diagnose a problem like this with a one-line description. If you post the image you are trying to draw and/or the code that is doing the drawing, it'll help. I'm not aware of any situation that would cause the colors to change unless you are specifically passing a ColorMatrix to do so, but certain types of graphics may appear darker or degraded with slight scaling.
  3. It looks like you triggered automatic moderation. The post is still there, it is just needed to be approved. Sadly, vBulletin hides your own post from you in this case instead of showing an informative message about the status of your post. It was probably the images in your post that triggered the moderation. The forum software tends to be suspicious of users with relatively low post counts.
  4. These sound like homework or test questions. If you're going in for an interview where you're expected to be familiar with these topics, trying to learn everything about programming all at once is a fantastic waste of time. If you explain your situation a bit better and demonstrate that you have made a fair effort to understand these concepts, I'll feel much more inclined to try and point you in the right direction.
  5. First, make sure you understand exactly what format the hex needs to be in. Must there be one and only one space between each value? Or can there be more spaces? Tabs? New-lines? And must there be two digits for each value? Or can values less than 0x10 be represented by a single digit? It's easier to write code when you know exactly what it's supposed to do. Assuming that the desired format is that each value be represented as one or two digits with one and only one space between each value, and no other whitespace or other characters, the simplest way to parse the text would be to use the string.split function to split the string into an array of value strings. You can then use the Integer.Parse or Integer.TryParse method to parse each string in the array, and write the value to the file. The problem with this approach is that, if you are dealing with enough data, you'll generate an enormous number of objects for the garbage collector to manage. If you're only dealing with smaller amounts of data, a solution that involves fewer than a dozen lines of code is probably ideal. If you find the performance to be unacceptable, then you can start looking into parsing the numeric values yourself without splitting up the string and calling Integer.Parse.
  6. Based on what Google has to say, System.Windows.Forms.AxHost.InvalidActiveXStateException is often thrown when you try to access an ActiveX component that is not fully initiailized. (It's hard to do more than guess and Google when I don't know anything about the control in question.) Not being much of an expert on the subject, if the Axpass.Axiepass class is written as an ActiveX control, I'm wondering whether the problem could be related to the fact that after you instantiate it, you don't place it in a control. After all, you don't get the exception when you place the control on a form. The empty string that gets returned could likely be a completely separate issue. I have no idea what the function does, how it does it, or whether it does it 100% right. (Just because it works in VB6 doesn't mean everything is 100% kosher. It's possible to do something incorrectly and still have it succeed in certain circumstances.) You can try double-checking the ActiveX source to make sure everything looks spiffy, and you should definitely check and make sure you are using the control exactly the same in .NET that you are in VB6. Maybe there's an initialization method that needs to be called or a property that needs to be set. The .NET WinForms designer may also be setting some properties that the VB6 designer did not, or vice-versa.
  7. The URI class should be able to do what you need. Check out the Uri.MakeRelativeUri function.
  8. It depends on exactly how you would like to limit the length of the text. It sounds like you want to limit the text to how much fits in the control visually. You can specify a maximum number of characters using the MaxLength property. That's the simplest solution, but may not work exactly the way you want. If you want to limit the input by how much text the control can hold visually, you can handle the TextChanged event and see if the new text fits in the text box. If not, revert to the previous text. In order to see whether the new text fits, you would want to use a Graphics object (PSA: Please allocate and dispose responsibly) and call the MeasureString function (you may need to specify a StringFormat or some other info if the measurements don't seem right). When trying to change the textbox behavior like this, it's often difficult to get the cursor to act in an intuitive way (you'll see what I mean if you try it).
  9. Does the autocomplete feature of the text and combo box controls suit your needs? Set AutoCompleteMode to Suggest or SuggestAppend, AutoCompleteSource to CustomSource, and AutoCompleteCollection to your list of suggestions. If you need something custom, writing your own auto complete control is hardly trivial. Since you're specifically asking about the popup, I can give you a tip or two. The popup needs to be implemented as its own form. You would need to look up how to properly set the styles (and maybe some other properties... I don't remember) of the form so that it doesn't take focus. You want the textbox and its containing form to keep focus.
  10. So, if you step through with the debugger, where does it get to? I don't see an obvious reason that the form is not closing, but I did notice this: If IsDiffrent = True Then Dim Answer As Byte = MsgBox("Do you wish to Save Changes?", MsgBoxStyle.YesNo) If Answer = 6 Then Call Save(True, "Closing") End If Else Me.Close() End If This code seems odd for a FormClosing event handler. You shouldn't be calling Close in the FormClosing event handler; you're already closing (in fact, something bad happened when I called Me.Close in the FormClosing handler). If you want to let the form close, do nothing. If you want to prevent the form from closing, set e.Cancel to true. In order to get access to 'e', you need to use the complete event signature for your handler, but it doesn't look like you actually intend to prevent the form from closing. ' change Private Sub FormClosing() Handles Me.FormClosing ' to Private Sub FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles Me.FormClosing The best suggestion I can offer is to use the debugger. Step through the code and find out what it's doing that it shouldn't be doing. On an unrelated note, why code like this: Dim Answer As Byte = MsgBox("Do you wish to Save Changes?", MsgBoxStyle.YesNo) If Answer = 6 Then when you can code like this? Dim Answer As MsgBoxResult = MsgBox("Do you wish to Save Changes?", MsgBoxStyle.YesNo) If Answer = MsgBoxResult.Yes Then That code tells me you aren't using Option Strict. I would very, very strongly advise you to use Option Strict. It might seem a bit inconvenient until you get used to it, but Option Strict is a good thing.
  11. You gotta at least try, man. Suppose FirstD = 0 and X = -1. (FirstD + X) evaluates to -1, which means you are accessing chosen(-1, SecondD + Y). chosen(-1, anything) does not exist. -1 is not a valid subscript for the first dimension. What would it mean to access chosen(-1, anything)? What do you think should happen in this case? Take a moment to think about it. The solution should naturally come from the answers to these questions, so really take a moment. Now that you've thought it over for a moment, you've probably realized that what it means to access chosen(-1, anything) is that you are trying to access outside the game field. So, what should happen in this case? Well, you know there are no mines outside the game field, so you should make a point of not checking locations outside the game field. How do we accomplish this? Start with a simple change in the code. Not strictly necessary, but it makes things easier. If chosen(FirstD + X, SecondD + Y) = True Then number += 1 ' Becomes [color="Red"]Dim gameFieldX As Integer = FirstD + X Dim gameFieldY As Integer = SecondD + Y[/color] If chosen([color="Red"]gameFieldX, gameFieldY[/color]) = True Then Number += 1 Now, we know that we don't want to check for mines in locations outside the game field. That means that first we need to figure out whether the location is within the game field or not. How? Well, if gameFieldX is less than zero, then we are looking beyond the left edge of the game field. If gameFieldX is greater that XLength, we are looking beyond the right edge of the game field. We can use the same logic to determine whether we are looking beyond the top or bottom of the game field. Here is some pseudo-code, with italics to indicate fill-in-the-blanks. Dim IsOutsideGameField = ([i]isBeyondLeftEdge[/i]) Or _ ([i]isBeyondRightEdge[/i]) Or _ ([i]isBeyondTopEdge[/i]) Or _ ([i]isBeyondBottomEdge[/i]) Once we know whether the location is outside the game field, we know whether or not to check that spot for mines. Put it all together: Dim gameFieldX As Integer = FirstD + X Dim gameFieldY As Integer = SecondD + Y Dim IsOutsideGameField = ([i]isBeyondLeftEdge[/i]) Or _ ([i]isBeyondRightEdge[/i]) Or _ ([i]isBeyondTopEdge[/i]) Or _ ([i]isBeyondBottomEdge[/i]) ' Are we inside the gamefield? If Not IsOutsideGameField Then ' If so, check for a mine! If chosen(gameFieldX, gameFieldY) = True Then Number += 1 End If
  12. I started reading the code and trying to figure out what was wrong when I realized, you don't explain what behavior you are expecting to see and what behavior you are actually seeing that is incorrect. Without comments, I had a tough time understanding how you're actually going about setting up the playfield. But 'll give it a whirl. Let's see how I do. The most obvious issue is that it looks like you aren't doing bounds checks. For FirstD As Integer = 0 To Xlength For SecondD As Integer = 0 To YLength ' ... For X As Integer = -1 To 1 For Y As Integer = -1 To 1 [color="Red"]If chosen(FirstD + X, SecondD + Y) = True Then number += 1[/color] Next Y Next X ' ... Next SecondD Next FirstD What happens on the highlighted line when, say, FirstD = 0. X loops from -1 to 1, so you access the array from (FirstD - 1) to (FirstD + 1). And what's the value of (FirstD - 1) when FirstD = 0? You need to make sure that your indecies are valid when accessing an array. The reason you probably aren't seeing an exception is because .NET has a known problem of swallowing exceptions (you never get an error) in the Form.Load event. I think this problem only affects the 64-bit version of the run-time, but I'm not sure. It would explain why the code stops running on the line you mentioned. I generally avoid running any code in the Load event because of this problem, unless I'm doing something Q&D. The constructor (Sub New) would probably be a good place to run this code, but VB tries to hide the constructor from you. (The constructor is probably in the form's .designer.vb file, hidden by default.) Did I do good?
  13. LamKat, this is recursion in it's most basic form. First, make sure you need recursion. Are the controls you need to access all contained directly within one container? Don't assume. Check. A control that hosts other controls might manage it's layout by placing the hosted controls inside child controls. For example, I believe that each half of a SplitContainer is a separate Panel control. If you add a control to the SplitContainer, it actually gets added to a Panel within the SplitContainer. Does a TableLayoutPanel do the same thing? You'll have to check. Look at the documentation, or examine it during runtime in the debugger. If your controls are nested (placed in sub-controls), you'll need recursion. If they aren't nested, you just need to loop over the container's Controls collection. ' This works if children are not nested For Each child As Control In ContainingPanelOrTableOrWhateverTheCaseMayBe.Controls DoWhatWeNeedToWith(child) Next If you do need recursion, and you aren't familiar with the topic, read a tutorial. Then apply what you learn to the situation at hand. Here is a start: Sub DoSomethingWithAllContainedPanels(ControlCollection controls) For Each child As Control In controls If child Is Panel DoWhatWeNeedToWith(child) End If If child.Controls.Count > 0 Then ' Child is a container and might contain panels ' Todo: loop over the child's controls (RECURSION) End If Next End Sub
  14. GDI+ lacks the ability to distort images the way you would need to in order to draw textured 3D graphics with perspective. The wire-frame probably wouldn't be too difficult if you know the mathematics involved. You could either precalculate the vertices and rotate them using a matrix or calculate the rotated vertices on the fly. Then it's just a matter of connecting the dots. So how do you calculate the vertices? I don't know. I could sit down and work it out, but it would probably be simpler to find somebody who already knows, and who can give you an optimal solution.
  15. Ideally, the framework would include a DeepCopy function. The needed functionality is already implemented in the BinaryFormatter class. If this is a simple class, rolling your own deep copy function could be as simple as manually copying objects and assigning them to fields. And, as much as I am a champion of mutable types, using immutable types would make cloning trivial, as long as it doesn't cause the GC to thrash. As to the question, I don't seem to be having the same problem with the run-time error. This is the code I used, which worked fine. namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var s = new test.c_kaprical.c_solarSystem(); var y = test.c_kaprical.c_solarSystem.Clone(s); } } } namespace test { using System; using System.IO; using System.Runtime.Serialization.Formatters.Binary; [serializable] public class c_kaprical { //my objects [serializable] //<- this does not help. public class c_solarSystem { //my objects public static c_kaprical.c_solarSystem Clone(c_kaprical.c_solarSystem newClone) { MemoryStream m = new MemoryStream(); BinaryFormatter b = new BinaryFormatter(); b.Serialize(m, newClone); m.Position = 0; return (c_kaprical.c_solarSystem)b.Deserialize(m); } } } } Note that I changed "class" to "static" on the Clone method. I'm guessing that's just a transcribing error. Other than that, everything seems to be spiffy, but I'm working with a skeleton class here. If any of your fields are declared with non-serializable types, you will still get the error you're seeing. [serializable] public class c_kaprical { //my objects [serializable] //<- this does not help. public class c_solarSystem { [color="Red"] SomethingElse anObject; // <-- ERROR: Field is of a non-serializable type! [/color] public static c_kaprical.c_solarSystem Clone(c_kaprical.c_solarSystem newClone) { // ... } } // Not serializable class SomethingElse { } } So my best guess: something in your object tree isn't serializable. The exception message should help you figure out what is causing the problem. The above code gave me this error: Type 'test.c_kaprical+SomethingElse' in Assembly 'ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
  16. Well, firstly, the call to Update isn't even necessarily required. Depending on the circumstances, the painting may occur immediately, or it may be delayed until the message queue is emptied, or it may be delayed a certain amount of time. But if you are calling Update, and you're still getting choppy animation, it may simply be that you're pushing the limits of GDI+. The mechanics of the paint event are this: when Windows feels it is appropriate, it issues a WM_PAINT message to the window in question. WinForms receives the WM_PAINT message, and in turn, calls the OnPaint method, which you may override. Control.OnPaint raises the Paint event (which is why it's important to call the base methods in these event method overrides). So, in short, calling Update should work with either the Paint event or the OnPaint method.
  17. Assuming that the -8 is an exponent, yes. Those are two different ways of representing scientific notation, the former generally used in mathematics, the latter generally used with computers and calculators. The E is shorthand for "times ten raised to the power of", so 5.6704 × 10⁻⁸ is the same as 5.6704E-8.
  18. The approach you're using is bound to have problems. You might want to do away with the PictureBox. You can use the PictureBox as a drawing container, but it won't really help unless you have a complicated user interface and need the docking/anchoring behavior for proper layout and positioning. I'll explain how you can do the drawing directly on the Form. For starters, things will look their best if the form is double-buffered, so I recommend you set your form's DoubleBuffered property to true. As a general rule, and especially when double-buffering, you want to do all of your drawing in the form's Paint event. This is simple enough to set up: [color="Red"]Private Sub Form_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint ' Draw here, using the e.Graphics object End Sub[/color] Now, when you draw, the drawing surface may or may not be cleared automatically. This depends on whether or not the form has it's opaque style flag set. I think by default, the drawing surface will be cleared automatically, but you'll want to double-check (or, you'll find anyways out when you try to draw your moving circle). I gather that you know how to draw a circle, but I'll throw the code here for completeness. [color="Red"]Dim CircleLocation As Point Const CircleDiameter As Integer = 750[/color] Private Sub Form_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint [color="Red"] Dim circleBounds As New Rectangle(CircleLocation.X, CircleLocation.Y, CircleDiameter, CircleDiameter) e.Graphics.FillEllipse(Color.HotPink, circleBounds)[/color] End Sub The location the circle will be drawn at is specified by CircleLocation. To move the circle, we need to change the value of CircleLocation and re-draw the circle. We would do this in a loop or with a timer in your case. Updating CircleLocation is easy enough: [color="Red"]' Move right one pixel CircleLocation.Offset(1, 0) ' Move up two pixels CircleLocation.Offset(0, -2)[/color] The process of redrawing requires some explanation. When you do your drawing in the Paint event, you don't directly call the drawing code. Instead, you invalidate the form or control that needs to be drawn. Invalidation tells Windows that something needs to be drawn, and Windows calls your Paint event for you. You can invalidate the entire form, to redraw the whole thing... ' Move up two pixels CircleLocation.Offset(0, -2) [color="Red"]Me.Invalidate()[/color] Or, you can specify a rectangle to redraw, which requires more effort, but gives better performance ' Move up two pixels [color="Red"]Dim oldRect As New Rectangle _ (CircleLocation.X, CircleLocation.Y, CircleDiameter, CircleDiameter) [/color]CircleLocation.Offset(0, -2) [color="Red"]Dim newRect As New Rectangle _ (CircleLocation.X, CircleLocation.Y, CircleDiameter, CircleDiameter) ' We will redraw the area containing both the old and new locations of the circle Dim invalidRect As Rectangle = Rectangle.Union(oldRect, newRect) Me.Invalidate(invalidRect)[/color] There is still one problem, though. When you invalidate a control, there is a tiny delay before it is redrawn. The reason for this is to let Windows make things more efficient. If you invalidate more than one thing in a small amount of time, waiting a tiny bit gives Windows the chance to combine all the drawing into a single Paint event. Normally this is a good thing, but you don't want to combine your Paint events, because that would ruin your smooth animation. The solution is easy. If you call the Update method on a control or a form, it will be drawn immediately without delay. ' Move up two pixels Dim oldRect As New Rectangle _ (CircleLocation.X, CircleLocation.Y, CircleDiameter, CircleDiameter) CircleLocation.Offset(0, -2) Dim newRect As New Rectangle _ (CircleLocation.X, CircleLocation.Y, CircleDiameter, CircleDiameter) ' We will redraw the area containing both the old and new locations of the circle Dim invalidRect As Rectangle = Rectangle.Union(oldRect, newRect) Me.Invalidate(invalidRect) [color="Red"]Me.Update()[/color] That should do the trick. I took a wild guess and hoped you wanted VB, but if you program in C#, you should still be able to understand it, and if you do program in VB, be warned that there are probably syntax or other minor errors in the code; I did not type any of it into the IDE. As long as you understand the code, you should have no problem getting it to work.
  19. Actually, it's strange how similar that is to a loosely-formed idea that has been floating around my head for a while. I thought it would be cool to have a space exploration game with action/RPG elements mixed in, but I've never investigated the idea or hashed out the details because if I get started with something new I'll never finish what I've got going now. So now I'm a bit curious. Is this an XNA game? What sort of gameplay is involved?
  20. Well, I thought I understood the math behind this, and I typed up a big long explanation about how I came to the answer that I came to, and before submitting my post, I tried a few more examples and realized I have no idea what I'm talking about, and that I just stumbled on a few cases where my bad math just so happened to give useful answers. So here's the answer I came up with without understanding how. If you take the cube root instead of the square root, you'll get a curve. Is it the curve you want? I'm not sure. Were you looking for a specific curve? I did. I didn't have time to respond, I spent so much time on my (first) answer :) I'll send you a PM.
  21. If I understand correctly, in your example you're looking for a random number generator where the number zero has almost no chance of coming up, and as you approach 100 each successive value becomes more likely. 100 would be twice as likely as 50 and 50 would be twice as likely as 25, and so on. Is this right? Even though we often generate random integers, the random number generator always starts with a random fractional number between 0 and 1 (to be more accurate, greater than or equal to zero, and less than one). Suppose we ask for a random integer from 0 to 99. The generator computes a number between 0 and 1, and multiplies that number by 100. This gives us a value that is 0 or higher and less than 100. Then the generator chops of the decimal part (truncation). This gives us an equal chance of getting any integer from 0 to 99. Now, if we get our hands on that randomly generated value between 0 and 1, we can do the multiplying and truncating ourselves, with the added bonus of being able to mess around with the random number to change the odds. We can actually get that random fractional value with the Random.NextDouble function. Let's start by generating a random number from 0 to 99, with equal odds for each number. We'll show the frequency of each number generated, as a percentage, in a ListBox. Const range As Double = 100 Const iterations As Long = 10000000 ' We will keep track of the frequency that each number from 0 to 99 is generated Dim Frequency(99) As Long Const FrequencyFormat As String = "{0}: {1}%" Public Sub DoRandomness() Dim r As New Random For i As Integer = 0 To iterations - 1 ' Get our random value where: 0 <= value < 1 Dim randomFraction As Double = r.NextDouble() ' Multiply to get the value in the range of 0 <= value < 100 Dim scaledValue As Double = randomFraction * range ' Truncate to get our final value from 0 to 99 Dim truncatedValue As Integer = CInt(Math.Floor(scaledValue)) ' Record the number that was generated Frequency(truncatedValue) += 1 Next End Sub Public Sub ShowRandomness() For iFreq As Integer = 0 To UBound(Frequency) ListBox1.Items.Add( _ String.Format(FrequencyFormat, iFreq, (100 * (Frequency(iFreq) / iterations)).ToString("0.00"))) Next End Sub Now, to change the odds, we can apply mathematical transformations to our randomly-generated fractional value. If you use a graphic calculator to graph the equation y=x with a view window of (0,0) to (1,1), you'll see that the curve moves from (0,0) to (1,1) in a straight line. This is our base-line where each number is just as likely to be randomly generated. Now, if you compare the graph of y=x to a graph of y=x^2, you'll see that y=x^2 curves below the line, indicating that smaller numbers are more likely to be generated than larger numbers. If we square our random fraction before multiplying and truncating, we'll get more small numbers and fewer large numbers. If we compare y=x to y=x^0.5 (square root), you'll see that y=x^0.5 bows up above the line. This indicates larger numbers are more likely to be generated. This is what you want. In fact, this produces random numbers where a number that is twice as large is twice as likely to be produced. We can make one small change to the program and see for ourselves. Public Sub DoRandomness() Dim r As New Random For i As Integer = 0 To iterations - 1 ' Get our random value where: 0 <= value < 1 Dim randomFraction As Double = r.NextDouble() [color="Red"] ' Take the square root to make large numbers more likely. randomFraction = Math.Sqrt(randomFraction)[/color] ' Multiply to get the value in the range of 0 <= value < 100 Dim scaledValue As Double = randomFraction * range ' Truncate to get our final value from 0 to 99 Dim truncatedValue As Integer = CInt(Math.Floor(scaledValue)) ' Record the number that was generated Frequency(truncatedValue) += 1 Next End Sub Run it and you'll see that, for example, 25 comes up about half as often as 50.
  22. This code works just fine for me. What is the problem you are having? Is the event not being raised? Or are you not getting the keycode you are expecting? private void webBrowser1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) { if (e.Modifiers == Keys.Control && e.KeyCode == Keys.C) { Clipboard.SetText(webBrowser1.DocumentText); } } There are some potential problems with this approach, depending on what you're doing with this program. If I select text in a textbox within the browser and try to copy it, I end up getting the page's HTML on the clipboard instead of the text selected in the textbox. You'll want to be aware of quirks like this if it's something that might be a problem.
  23. Understandable, but a very simple change could help you avoid directly referencing your game object. class AGameClass { // Used to lock syncronous operations object _taskQueueLock = new object(); // Our queue of tasks Public List<Action> taskQueue = new List<Action>(); // Can be called from any thread public void QueueAction(Action action) { lock(_taskQueueLock) { _taskQueue.Add(action); } } // Will be called from main thread protected override void Update(Some parameters) { RunQueuedTasks(); // Other stuff } // Will run queued tasks on main thread and block threads that try to queue more tasks in the interim // Watch for race conditions! If you want a queued task to be able to enqueue more tasks, you'll need // a better approach for managing your task queue (a thread-safe list class should work). private void RunQueuedTasks() { lock(_taskQueueLock) { foreach(var action in _taskQueue) { action(); } _taskQueue.Clear(); } } [color="red"] // Assuming _videoTexture_1 has already been instantiated and wired for events AnotherClass _videoTexture_1; AnotherClass _videoTexture_2; [/color] [color="red"] _videoTexture_1_AThingHappened(object sender, EventArgs e) { // Dispose the first video texture and create the second QueueTask(new delgate() { _videoTexture_1.Dispose(); CreateAndInitialize_videoTexture_2(); }); }[/color] } class AnotherClass { [color="red"] public event EventHandler AThingHappened; [/color] protected override void SomethingHappened() { [color="red"] // Raise an event when appropriate var tmpAThingHappened = AThingHappened; if(tmpAThingHappened != null) tmpAThingHappened(this, EventArgs.Empty); [/color] } } The effect of the code is the same, but the game creates each video texture instead of one creating another. It makes more sense to have the game class managing these things (or a Scene or Sequence or Montage or whatever class if you're working on a larger, more complex project) than to have the video texture doing more than being a video texture.
  24. I'm not sure whether you mean that you don't want your VideoTexture to reference the main form, or that you don't want your game class to reference the main form. It shouldn't matter, though. You can have your Game class queue code or tasks to run on your main thread, and have the Update routine perform these tasks. Since the Update method is run on the main thread, the tasks you queue will be run on the main thread. class AGameClass { [color="Green"] // Used to lock syncronous operations[/color] object _taskQueueLock = new object(); [color="Green"] // Our queue of tasks[/color] Public List<Action> taskQueue = new List<Action>(); [color="Green"] // Can be called from any thread[/color] public void QueueAction(Action action) { lock(_taskQueueLock) { _taskQueue.Add(action); } } [color="Green"] // Will be called from main thread[/color] protected override void Update(Some parameters) { RunQueuedTasks(); [color="Green"] // Other stuff[/color] } [color="Green"] // Will run queued tasks on main thread and block threads that try to queue more tasks in the interim // Watch for race conditions! If you want a queued task to be able to enqueue more tasks, you'll need // a better approach for managing your task queue (a thread-safe list class should work).[/color] private void RunQueuedTasks() { lock(_taskQueueLock) { foreach(var action in _taskQueue) { action(); } _taskQueue.Clear(); } } } class AnotherClass { protected override void SomethingHappened() { aGameObjectThanImReferencing.QueueAction( new delegate() { [color="Green"] // Dispose method can free unmanaged resources, including // threads and graphic resources [/color] SetUpAnotherVideo(); this.Dispose(); }); } } Understand, I'm not a threading expert. That, and this is sort of off the top of my head, but it seems about right to me... :>
  25. I think that the best thing to do would be to raise an event on the main thread or otherwise notify the main thread when the video is done. The main thread can get the second video going and let the VideoTexture object's thread complete gracefully instead of aborting the thread, and then dispose it.
×
×
  • Create New...