And this is why you should never write code while you’re high

I’m sorry, this post is far too technical. But other programmers will follow what I’m ranting about… I could post this to my programming blog, but since the topic is the effect of meth on the way I thought and the quality of the code I wrote, I’m posting it here instead.

For no particular reason, I was thinking of reusing the video player that I wrote a few years ago while I was still using, and it turned out to be a very bad idea. The thing is, I did a good job of the GUI. The player looks nice enough…

image

And it also has some cool features, not that anybody in their right mind would ever want to watch Depeche Mode at 25% of normal speed, or 200% – yes, it does have some goofy features, but they seemed important at the time. Anyway, I like the GUI, which has three different themes, and looks prettier than any of the other players I have. The problem is, I totally mixed the video player logic with the user interface. If I’d made a nice abstracted player class of some sort, it would be reusable, but as is, it would take many hours to separate the logic from the UI.

But that’s not the worst of it. The video I played now was higher resolution that my screen size, and my player would not play full screen. Whenever I tried, it played at “Auto 3/4 screen size” instead. (A calculated size that my player exposes as one of the possible options, but it’s not supposed to behave that way when you select full screen.) i.e. These…

image

So off I go, debugging back into the world of the over-engineered monstrosity I coded about three years ago while I was as high as a satellite:

        /// <summary>Common handler for zoom controls.</summary>
        /// <remarks>Each zoom control's Tag property is set to the
        /// numerical value of the appropriate MediaZoom.</remarks>
        private void Zoom_Click(object sender, EventArgs e)
        {
            var zoom = MediaZoom.ActualSize;
            var item = sender as ToolStripItem;

            if (item != null)
            {
                if (Enum.TryParse((string)item.Tag, out zoom))
                {
                    zoom = AdjustOversizeVideo(zoom);

                    var transitionToFullScreen = zoom == MediaZoom.FullScreen && MediaZoom != MediaZoom.FullScreen;

                    ZoomTo(zoom == MediaZoom.FullScreen ? MediaZoom == MediaZoom.FullScreen ? Settings.Default.MediaPlayer_PreviousZoom : zoom : zoom);

                    if (zoom == MediaZoom.FullScreen)
                        TaskbarList.MarkFullscreenWindow(this.Handle, transitionToFullScreen);

                    if (zoom != UI.MediaZoom.FullScreen || !transitionToFullScreen)
                    {
                        /* Unfortunately, we have to jump through some hoops to avoid losing the Windows
                         * Aero visual affects on the windows border.
                         * i.e. Need to recreate the window handle, but that will leave the Video window
                         * with an invalid handle for an owner, so first remove the owner, then restore
                         * it afterwards. */
                        if (!isAudioOnly && videoWindow != null)
                        {
                            if (videoWindow.put_Visible(OABool.False) == 0 && videoWindow.put_Owner(IntPtr.Zero) == 0 &&
                                mediaEventEx != null && mediaEventEx.SetNotifyWindow(IntPtr.Zero, 0, IntPtr.Zero) == 0)
                            {
                                reinitializing = true;
                                this.RecreateHandle();

                                ReinitializeVideoWindow();
                                mediaEventEx.SetNotifyWindow(this.Handle, WMGraphNotify, IntPtr.Zero);
                                reinitializing = false;
                            }
                        }
                    }
                    BringToForegroundAndActivate();
                }
            }
        }

Ohh, that’s some shitty code. It’s mostly crap, written on Windows 7 and working around a strange issue where resizing my player window would lose the Windows 7 Aero crap, so I had to jump through some hoops. None of that shit is necessary anymore.

So I set a breakpoint on the line that begins with “var transitionToFullscreen =”, thanking my former self for at least using verbose and descriptive variable names. Lo and behold, the zoom variable, which as I recall holds the user’s selected choice for the screen view size, is set to 3/4 screen. What the fuck? I know I chose full screen.

Oh dear. Since I coded this in another lifetime, and don’t recall what I was thinking after being awake for around a week, let’s go see what AdjustOversizeVideo does…

        private MediaZoom AdjustOversizeVideo(MediaZoom zoom)
        {
            // Adjust zoom if it is bigger than screen size
            var videoSize = VideoSize;
            var screenSize = Screen.FromControl(this).Bounds.Size;
            var factor = 1D;

            switch (zoom)
            {
                case UI.MediaZoom.ActualSize:
                    factor = 1D;
                    break;
                case UI.MediaZoom.DoubleSize:
                    factor = 2D;
                    break;
                case UI.MediaZoom.HalfSize:
                    factor = 0.5D;
                    break;
            }

            if (!isAudioOnly && videoSize != Size.Empty
                && (videoSize.Width * factor > screenSize.Width && videoSize.Height * factor > screenSize.Height))
            {
                zoom = UI.MediaZoom.AutoTwoThirdScreen;
            }

            return zoom;
        }

Fuck. In my infinite (lacking) wisdom of tweaking, I went to an awful lot of trouble to adjust the video size, for cases when the video size is bigger than the screen. In the event of the video size being greater than the screen size, I change the value of the variable that represents the user selection to be 3/4 screen size automatically – without even checking if the user actually wanted to go full screen. Why? Why not just use full screen anyway, when I know the video is bigger than the fucking screen? (Maybe because I was high.)

Anyway, this will fix it. Actually I also didn’t check for my two calculated video sizes being passed in. The solution is that the code should do nothing if any of those were passed in.

        private MediaZoom AdjustOversizeVideo(MediaZoom zoom)
        {
            if (zoom != MediaZoom.FullScreen &&
                zoom != MediaZoom.AutoThreeQuarterScreen &&
                zoom != MediaZoom.AutoTwoThirdScreen)
            {
                // Adjust zoom if it is bigger than screen size
                var videoSize = VideoSize;
                var screenSize = Screen.FromControl(this).Bounds.Size;
                var factor = 1D;

                switch (zoom)
                {
                    case UI.MediaZoom.ActualSize:
                        factor = 1D;
                        break;
                    case UI.MediaZoom.DoubleSize:
                        factor = 2D;
                        break;
                    case UI.MediaZoom.HalfSize:
                        factor = 0.5D;
                        break;
                }

                if (!isAudioOnly && videoSize != Size.Empty
                    && (videoSize.Width * factor >= screenSize.Width ||
                    videoSize.Height * factor >= screenSize.Height))
                {
                    zoom = UI.MediaZoom.AutoThreeQuarterScreen;
                }
            }
            return zoom;
        }

Hey, I guess I should be thankful that this thing works at all.

Here’s some more awfully messy code from the same form… I would never have written anything like this sober – with the video player and UI code all jumbled together.

And this is why you should never code while using drugs.

        private async void PlayMovieInWindow(string file)
        {
            Action<Exception> handleException = ex =>
            {
                var errorMessage = ex.Message;

                if (!string.IsNullOrEmpty(errorMessage) && ex.HResult != (int)HResult.E_FAIL)
                {
                    ex.Log();
                    MessageBox.Show(errorMessage, "Error playing file", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                Dispose();

                // Experimental (and probably unwise). Sets the now dangling singleton pointer to a new instance.
                Singleton<MediaViewer>.Reinitialize(new MediaViewer());
            };

            var hr = 0;

            if (string.IsNullOrEmpty(file))
                return;

            // Get the graphbuilder object
            graphBuilder = new FilterGraph() as IGraphBuilder;

            try
            {
                var hres = (HResult)graphBuilder.RenderFile(file, null);

                // Query for video interfaces, which may not be relevant for audio files
                videoWindow = graphBuilder as IVideoWindow;
                basicVideo = graphBuilder as IBasicVideo;

                // QueryInterface for DirectShow interfaces
                mediaControl = graphBuilder as IMediaControl;
                mediaEventEx = graphBuilder as IMediaEventEx;
                mediaSeeking = graphBuilder as IMediaSeeking;

                // Query for audio interfaces, which may not be relevant for video-only files
                basicAudio = graphBuilder as IBasicAudio;
                HasAudio = basicAudio != null;

                if (!Visible)
                    await WaitVisibleAsync();

                ReinitializeVideoWindow();

                // Is this an audio-only file (no video component)?
                CheckVisibility();

                // Have the graph signal event via window callbacks for performance
                hr = mediaEventEx.SetNotifyWindow(Handle, WMGraphNotify, IntPtr.Zero);
                DsError.ThrowExceptionForHR(hr);

                /* When the clip has no video, we remove the Form borders and add borders to the controls instead.
                 * The normal controls' height is not enough (causes the volume slider's thumb image to be clipped). */
                var controlsSize = new Size(0, isAudioOnly ? ControlsHeightAudioOnly : ControlsHeightNormal);

                if (controlsPanel.MaximumSize != controlsSize)
                    controlsPanel.MaximumSize = controlsSize;

                if (controlsPanel.MinimumSize != controlsSize)
                    controlsPanel.MinimumSize = controlsSize;

                if (!isAudioOnly)
                    GetFrameStepInterface();

                ZoomTo(mediaZoom = AdjustOversizeVideo(mediaZoom));
                InitializeZoomControls();
                Seeking = true;
                SetRate(Settings.Default.MediaPlayer_ResetPlayRateOnFileOpen ? 1.0D : Settings.Default.MediaPlayer_Rate);

                // Run the graph to play the media file
                hr = mediaControl.Run();
                DsError.ThrowExceptionForHR(hr);

                PlayState = PlayState.Playing;
                mute = VolumeController.Mute;
                currentVolume = Settings.Default.MediaPlayer_Volume;
                volumeSlider.Value = currentVolume;
                VolumeController.Volume = (int)volumeSlider.Value;
                UpdateVolumeControls();
            }
            catch (Exception ex) { handleException(ex); }
        }

        private async Task WaitVisibleAsync()
        {
            /* Filename is set and PlayMovieInWindowAsync is called before showing this form the first time.
             * This ensures that we start off with the right size, but we need to wait for the form to be visible
             * so that the video window has a valid window to which to render. */
            while (!Visible)
                await Task.Delay(1);
        }
Advertisements

About Jerome

I am a senior C# developer in Johannesburg, South Africa. I am also a recovering addict, who spent nearly eight years using methamphetamine. I write on my recovery blog about my lessons learned and sometimes give advice to others who have made similar mistakes, often from my viewpoint as an atheist, and I also write some C# programming articles on my programming blog.
This entry was posted in Addiction, Methamphetamine, Programming, Skepticism and tagged . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s