It’s ya boi Shark here for the second ThinkPad showcase post! This post has been a bit delayed due to my dissertation milestone that was due Friday, but here here it is! I’m looking at my most modern ThinkPads today; the Lenovo L430 and T430. Both are from the same generation (2013) and both were plus £100. The specifications were also basically the same with 2.6GHz Intel Core i5-3230Ms (Ivy Bridge), 8GB DDR3-1600, and 120GB SSDs.
Starting with the L430, here we have a lovely package that cost only £150! The L-series is Lenovo’s medium range ThinkPad series and is made with a plastic construction and bottom-firing speakers. This configuration also did not come with a ThinkLight. A part from the lid being heavily scratched, the machine is in good condition! It originally came with Windows 10 installed, which I replaced with Ubuntu 18 (as seen in the photo below) for a moment, but then went back to Windows 10 Education since I needed a dedicated Windows machine after selling my previous main machine (ASUS ROG laptop).
SN-L430 is tasked with dealing will all my Windows needs! This includes running legacy Windows software, DirectX game development, and checking cross-compatibility of software I’ve developed on Linux that is intended to be portable to Windows too.
T430 is one of my favourite ThinkPads (besides SN-X220 and SN-R60e). Costing around £100, it was a brilliant deal and is in really good condition too! We have up-firing speakers, ThinkLight, and the usual quality-feeling soft-touch coating on the body that has barely degraded (except for some corners)!
The machine is a current staple of for my university workflow, serving as my main serious driver alongside SN-X220 as my personal organiser. It’s software compliment includes some programming stuff like Anaconda, VS Code, Clion, and XAMPP.
All in all, both machines are great examples of eBay purchases going right! For the next post coming either next week or the week after, I’ll be showcasing my T41 and T42 and talking about some GPU reflow work I’ll be doing to the former!
January has probably been the busiest month in my entire life. No kidding! Constant work, personal projects, assignments, and very little free time to myself. But I am happy to say I have enjoyed all of it!
Since my last life update last month, I have had two coursework results back from my Computer Graphics and Tool Development for Computer Games modules. The former was a 2D OpenGL scene demonstration where we had to sample OpenGL objects and techniques and demonstrate them – from Vector Array Objects to hierarchical modelling. The demo at the time went well, and I got 88% in the end! The latter was building a Python missile command game clone with the Pygame engine and developing a small physics simulator called “Marble Madness” with a lecturer-developed engine (PGE). I had 90% on that one. So I’m happy with my performance last term to say the least!
For the second term, this module now focuses on 3D rendering in OpenGL and 3D modelling with Autodesk 3DS Max. Things have continued to go well this term, and 3D modelling is actually more fun than I imagined! It has been useful for my group project in another module as well! The programming side is obviously interesting, but we are still in the opening weeks and have not done a lot of programming for OpenGL 3D yet.
Tool Development for Computer Games
Whilst I don’t have anything against Python, the module is a lot more interesting for me this term now that we are starting to do C# GUI programming with XAML. Whilst I have done a few WinForms projects before, WPF is something I have never touched before! The coursework looks like a nice challenge too, which is to build a game level designer for a tile-based game. We are given the game and its source code and have to build the designer based on the code ourselves!
Data Structures & Algorithms With Object Oriented Programming This module recently had a coursework due on the 12th, which was the process scheduler assignment I talked about in a post back around late-December. Basically, we were given a public API to conform to and told to fill in the blanks in C++. My scheduler ended up being a multi-level queue with a custom algorithm that creates a cycle to prevent blocking (the act of higher priority items stopping lower priority items from being processed completely). The scheduler creates a cycle in which each level of priority (from 1 to 10) gets a certain amount of attention. Higher priorities get more attention than lower ones in the cycle, but the lowers still gets *some* attention rather than none.
Other than the coursework, this term has also taken up a slightly different theme. We are now covering different design and strategy patterns to OO programming. Whilst they certainly require a bit more thought to understand, one of the two we have learnt so far has already came in handy with my web work! The observer pattern, which states the relationship between a subject (essentially some hub) and its observers (dependencies like clients), is basically the same principle of the way I’m developing this small social network in PHP for my portfolio.
Professionalism: “Project FallingStar” Once again, the largest and most impressive thing I am involved with at University. My team has made significant progress and whilst we are far from having a complete game, the game is looking rather beautiful already! Besides defacto leadership and physics programming, I have also undertaken tasks for 3D modelling and special effects for the game. Like the last time I wrote about this, I have some little peaks for you:
I have also made a fair bit of progress with personal things as well. My Star Trek fan site, Path to 2265, remains a top priority for me and many improvements in the back-office have been made. The website’s search engine programming has transformed into a mature, secure and robust platform that allows the website to provide intelligent and weighted search results, whilst also providing internal benefits by allowing pages to be more dynamic and use the website’s database more. I’ve also been working on actual front-end content as well with Chapter 2 being released within a month or so and several more ships added; Polaris has a completed database entry, DY-732 has its specs mostly ironed out, and an upcoming design is due for completion soon:
I have also resumed limited work on my old GeckoFX-based C# browser KAubersnek. I’ve been adding a few features over the weeks and will likely continue full development when I have some time.
This is a fairly quick and fun (for me, at least) blogpost about something I have to consider for a university assignment.
The assignment revolves around developing a scheduler in C++ that could theoretically be applied as a process scheduling algorithm for an operating system. We were given a code spec to conform to, which consists of class and functions definitions for a integer Stack, Queue and Scheduler. The assignment mandates that we make all three paradigms operational (no surprise). Implementing the first two things was easy, but building a scheduler requires a lot of thinking. Thanks to the specification and the assignment briefing, we are shown that the scheduler operates with 10 priority levels (0 – lowest, 10 – highest) and it bares some relation (inheritance) to the Queue functionality.
You might be thinking: “Woah there Khalid, lot more thinking? Processing tasks based on priority levels is easy ’cause you just select the highest priority items first and go from there…”. Well in theory, that is an easy concept to understand. BUT with that specific approach, you could experience one of the most breaking problems in scheduling.
Blocking (which is the phenomenon where low priority tasks are ‘blocked’ from being processed by high priority tasks) could effectively break the integrity of a system that is supposed to take on more and more tasks whilst operating (like our process scheduler). Whilst those low priority tasks are supposed to be… well… low priority, they are not irrelevant and will need processing eventually. Even in scenarios where tasks are not added during operation (schedulers that have a predefined task list to complete), sequentially processing items from highest to lowest could result in the lower ones never being touched (at least until after an unreasonable amount of time) since there could be a huge amount of set items!
Imagine we have a system that has a million high priority tasks but just one low priority task. If the scheduler is processing sequentially, it will take a huge amount of time to reach that one low priority task. Surely, there has to be a better way?
With the use of some more processing power, there is. But you’re gonna have to wait to find out! I’m currently having an interesting time trying to select an appropriate method. I’ll likely report my findings after the assessment is submitted (because I do not want to give the answer away).
As of last Friday, I’m now off university for a few weeks. I thought it might be neat if I make a post about what I have done these last few weeks for university, so here goes!
“Project FallingStar” …is the single biggest thing I have been involved with this term. For the Professionalism module, we were put into groups (four, five (as it is for ours) or six people) and tasked with planning and building a 3D game from scratch whilst still learning the engine we have to use (Unity). I am pleased to say I have thoroughly enjoyed the project so far! The idea for our game is that the player builds modular space probes to send out on exploration and defence missions in the solar system. Despite initial doubts that our idea was too ambitious for a bunch of UNI students, our team (designated Team 1) is working well and our recent demo was well-received! My main contributions to the team have been physics programming (producing the gravity model) and leadership (defacto, since it was something that I naturally slipped into rather than being designated).
OpenGL coursework This coursework was also fun. In the Computer Graphics module, we have been learning the basics of OpenGL and the assessment was to compile a 2D OpenGL scene that makes use of advanced OpenGL features (compared to just using immediate mode rendering) such as Vector Buffer Objects (and Vertex Array Objects), hierarchical modelling, and transformations. Whilst I have to wait for my grade, the demonstration I have to my lecturer was well-received!
Python + Pygame This coursework was interesting ’cause I both did and did not enjoy it. The coursework was split into two tasks; building a missile command game clone with Pygame and then developing a small physics sim “Marble Madness” with a lecturer-created engine. Both tasks had their merits, which for me was mainly the fun of programming. What I did not like was that we could only develop the second part on Linux since the engine (PGE) is Linux-only. Whilst I have Linux at home nor is Linux THE problem, there is really only one computer lab in the university (where I work better at than home) that has Linux. This meant I could not always be guaranteed a computer since the lab was in high demand. I was even asked to leave for another class on two occassions, with can really be inconveniencing!
So yeah, that’s what I have been up to academically! In my spare time, I am continuing the development of Path to 2265 as another personal priority. I’ve recently made some huge underlying changes that I’ll be posting about this week!
So, it begins. Another year of work towards my future. My first impressions of the Year 2 (technically year 3 out of 4 considering my foundation year) modules are good. I am looking forward to all of them. I’m happy! 🙂
So, the modules.
Data Structure & Algorithms with Object-Orientated Programming is mainly C++, so who can complain? The Professionalism module ultimately involves building a game with the Unity engine in a group. We were put into teams based on our performance last year (apparently heavily weighted towards programming). I was put into Team 1 and so far the team seems great to work with! Tool Development for Computer Games (using Python and C#) and Computer Graphics (OpenGL-based) are great. Operating Systems Concepts, which focusing on how operating systems work, is interesting. The math module Computational Mathematics, unlike last year, actually involves some programming later on, so it is a welcomed change from the very static and boring maths module last year.
Coupled with all these modules, I have given myself a new weekly schedule that commands that I study certain topics for (at least) a set amount of time. These additional study periods are fully welcomed – I enjoy studying, and I feel it is a necessity that will allow me to continue the development and maintenance of my skills. I also needed something to fill out my Monday (which is completely free of lectures and tutorials) and days that I finish UNI early etc. Most of these scheduled study times are in 4-hour blocks, and exclusively involve C#, C++, Unity, Python, Website Development, OpenGL and “language of the week/month”. Most of these relate to what I do in a module that involves the subject, but Website Development is independent and currently dedicated towards my Starfleet’s Path to 2265 website, and “language of the week/month” is dedicated for me to explore a new programming language. For the next few weeks, this will be Java. Lua and Haskell are next!
Hopefully I will get back into the routine of personal blogposts again, since it has all been about my Star Trek-themed website for the last few weeks (posts about Starfleet’s Path to 2265 will be confined to Thursdays). I do want to document my progress throughout university more closely and share my academic experiences! 🙂
You will be pleased to know the solution works! I have yet to do extensive/thorough testing, although I am doing on-the-fly debugging in the meantime until I achieve this first operational milestone. And that is what I want to talk about. Milestones.
I do love my planning, and I have thought out a fair bit about what I want the program to be once it is done. So far, I have a well-defined operational milestone that I am dubbing “Full Operational Capability” (very professional sounding). This milestone is reached once the core functionality of the browser is complete. That means no advanced developer tools are being added at this stage, nor will the styling be finalised. Basically, the following criteria must be met:
Basic web functionality
Past and forward history traversing
Native search query forwarding
Basic user settings
Home page setting
Search engine setting
Basic UI layout settings (hiding the bookmark bar, etc.)
Basic bookmarking system
Tab-based bookmark-managing functionality
UI bookmark bar
Basic ‘luxuries’ (you could consider these non-essentials)
Custom source code view
Custom context menu for default right-clicking within the GeckoWebBrowser
Custom download management capabilities
This milestone determines how far the project will go. If I am unable to create a usable web browser by not meeting this criterion, I will either cancel the project or postpone it until a time I have learnt what I need to know to complete this. Remember, I am always learning.
However, if this milestone is reached, I will then begin work on the next two milestones:
Developer Tools Completion
This stage involves implementing some of the advanced developer features that the project is designed to accommodate. This includes the addition of a non-WYSIWYG webpage editor with helpful options designed to speed up the development of HTML and CSS code without the clutterful and fun-sapping ways of WYSIWYG designers such as Adobe Dreamweaver. This functionality is currently being explored in a project called “KAubershark”, which I am not prepared to reveal yet (it is still very rough and early)
UI Design Unification
This stage involves finalising the overall design of all aspects of the software. This includes making the design unique and unified across all forms, dialogs and controls. After this is done, the project will be complete.
I have not gone into too much detail for these milestones in case of further refinements to the ideas. What I gave you is a basic brief of what the work entails, but I do have other ideas that I am still playing around in my head with. Work on ‘KAubershark’ is currently on hold until the first milestone is complete. It originally started as a standalone idea as a non-WYSIWYG development suite, and what code I have done for it is currently in a separate solution. That work is mostly rough and is for the purpose of exploring the plausibility of the idea, since it will naturally be a huge task and I want to make sure it is worth the effort. The final way I am going to implement KAubershark is not finalised either. My two options are to integrate the work into KAubersnek’s solution, or keep it as a separate standalone software and add a bridge for the two applications to access each other.
So that is it for this post! I hope you appreciate the insight, and please watch this space!
KAubersnek is my project to create a personal (and only for me at this point) web browser that will aid me in developing websites by providing me with custom developer-focused tools (and will serve as a piece within my future portfolio of work). However. Currently, I am far from realising that goal. But for now, I have been making considerable progress in maturing the basic web browser itself into a usable frame to work with.
The UI is currently based heavily on the open-source Chromium (of which Google Chrome is a well-known release of) UI. But one of the goals for reaching what I am calling the “full operational capability milestone” is to have a custom tab design. However, designing the UI is currently taking a backseat role in favour of allowing the UI to be more flexible for when I add crucial features take enable the browser to be fully operational.
So that’s pretty much the overview, but today when I was working around a me-induced bug/oversight, I thought that I might be cool to write down this problem with a methodical solution so that I could convey what it is like to be a programmer (at least in my eyes) when solving a problem. Here goes nothing. Also, one more thing. This is written in a way that allows it to be understood (I hope) by almost anyone with at least some basic idea what programming is like. To that end, I will be attempting to explain some of the more complex concepts that people might have trouble getting their heads around. But I at least hope you know what a class, object or a control is. If not, you might want to look them up first.
The problem When loading a website in the browser, you had to remain on the current tab until the page was loaded. Otherwise, switching tabs during the download resulted in some of the results of the download (namely the website’s title) being applied to the wrong tab. This was because the code originally forwarded the downloaded title from the user control the GeckoWebBrowser object is a member of, to the currently-active tab on the TabControl object which is housed on the main form. As aforementioned, this was a simple oversight as it was just a case of the data being sent to the wrong object in some specific cases.
What it looks like
Listed process ‘chart’
A webpage download action is taken by the user within the browser; via URL navigation, web search or hyperlink navigation
The user switches tab whilst the download is in progress
The download completes within the other tab, and the DocumentComplete event is triggered on that instance of the browser
The DocumentComplete event gets triggered when the GeckoWebBrowser object declares that it has finished downloading the webpage and its content
The DocumentComplete event code sets the text of the currently-selected tab as the DocumentTitle of the downloaded webpage, as reported by the GeckoWebBrowser
There is no check/flag to see if this is the correct tab that actually contains the user-created control with its GeckoWebBrowser
Analysis The reason why this is not a simple cakewalk is because of how the structure of the program is. It is not one large object called ‘browser’. The ‘parental’ structure that I have to deal with looks like this:
The actual powerhouse under the hood (that is the browser) is the GeckoWebBrowser object.
The GeckoWebBrowser object is housed within a user-created control, which is a class that contains the GeckoWebBrowser object and all the controls needed to operate the browser at the basic level (buttons, address box, options menu, progress bar and status display label).
This user-created control is docked onto a TabPage object when the tab is first created. This TabPage is actually the object that contains the crucial property known as ‘Text’. This property is what gets updated each time a webpage is finished being downloaded.
The TabPages are then added to the TabControl’s TabPage collection. This collection is then represented as clickable tabs on the main form.
With that in mind, you can begin to picture what the issue is. Although the user-created control is docked onto a TabPage, that user-created control does not have a native ability to tell what its ‘parent’ object is. So, when the DocumentComplete event proceeded to update a TabPage’s ‘Text’ property, it does not care or recognise if the user switches TabPages by clicking one of the visual tabs. It just updates the selected tab. This problem is an oversight because I should have seen it coming, since I must put more code in to fix this either way. Now that I see what the issue is, I can now easily implement my three-part solution.
I added an integer variable inside the user-created control called ‘intPosition’. This variable will store a value that indicates what position its parent TabPage should be at within the TabControl’s TabPage collection (known as index). So now the code that updates the TabPage’s ‘Text’ will know what TabPage to apply the change to. This position variable is initialised as soon as after the user-created control instance and its mounting TabPage is being created, and the value is based off the current number of TabPages within the index.
I also added some code that updates the position variable in all opened instances of the user-created control when there is a change within the index. Changes to index are made when a tab is opened, closed or moved around. So this code is a must for such scenarios. For example; if I had three tabs open and I close the middle one, the third tab will have its position variable updated since it has now become the second tab in the index, and the browser would need to know that otherwise the program would literally DIE in runtime. Okay. Maybe not that extreme. But it would be bad.
The code within the DocumentComplete event is updated so that it references the TabPage it needs to access via the index (cross-referenced with the position variable) instead of accessing whatever is the currently-selected index is.
Code (You’ll have to excuse the amount of comments. They’re just there to explain the screenshots.)
Conclusion I actually have not tested this yet. It is almost the end of today, so I will enjoy a sleep before I make sure the changes work. In theory, this should work no matter what however. But I will let you know tomorrow. My next post on the subject will go more in-depth about the goals and milestones of the project.