Text Limit By Number of Lines

April 27, 2020

One of the benefit having MS Edge as a webkit browser, is that we can use webkit prefix more freely.

The common (annoying) UI request is text limit by lines. I often asked my PM for character limit instead, which may not be reliable.

In 2020, we can just use -webkit-line-clamp property. Firefox has supported it since last year as well.

@mixin line-clamp($total){
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
}

Assuming the container already has width, we can just apply the above styling.

(Very) Basic Cooking: Fried Egg

April 15, 2020

"An egg today is better than no egg tomorrow"

I have never cooked in my life before, apart from instant noodle.

Not anymore.

It is eatable.

I don't have any talent and big interest in cooking. My aunts have cooked for me and I feel grateful.

However I will probably need very basic cooking skills just for survival purpose.

First Impression of Go

April 11, 2020

Using something new in a limited time is actually quite thrilling.
I have a task for creating internal disposable tool for current project, and one way to make it more interesting is by using different language.

In this case, I use Google's Go programming language, which is growing in popularity.
My friends and ex colleagues from previous companies have used it for years, so I am way behind them in term of knowledge.
I have studied Go before in relatively limited scope, but I have never used it.

Now is still a good time for using Go. There's no need to structure code in GOPATH directory, which feels annoying for newcomer. Go module is also the official way of managing dependencies now.

I will likely post more detailed experience later (~ 1 month from now) after everything is settled. However I am satisfied so far.
It is a modern language designed for concurrency, yet relatively simple. There are few things, which I have mixed feeling, like the error handling pattern, and relatively different behavior of standard library from outsider perspective ( date format and regexp ).
However it is undoubtly a better language than PHP, which I use at daily work, and it has better runtime than Node.js.
Language wise, I like the syntactic sugar of Js more, but Js is single threaded. Node.js only has new Worker Thread officially since last year.

I expect Go will be still be relevant for the next 10 years.

I Have Been A Failure

March 30, 2020

Dear myself, I fucked up big time.

I spent my last 4 years achieving nothing special. Now is almost April 2020.

Lazy / Lack of Focus

I often told myself that I am smart.
I can study book / watch a lot of video tutorials in my spare time. However the most important thing is I have to use it to create something, which I didn't.
Knowledge in IT needs to be always up-to-date.
I told myself to learn / develop some app with Unity, Kotlin etc but in the end nothing happened.

Missed goals + Bad discipline

Time wait for nobody, I have failed to achieve some of my life goals.
I can only regret.

I have been overweight for several years, and I only start reducing weight last year.
I have habit of eating a lot at night, especially if I'm in bad mood. It is bad for my weight and my health. Issues like recurring knee injury after running and acid reflux are side effects from being overwright.
Now I am still overweight by 3-4 kgs based standard BMI.

I still can't do a lot of basic but important things like cooking.

Blog update

I don't use Ruby anymore. Today is the first time I touch Ruby for more than 3 years. I installed it just for maintenance of this Jekyll blog. I had to use old version of Ruby due to gems incompatibility.

I was going to update my blog with GatsbyJs. I was in the middle of Gatsby theme development, and somehow my focus was distracted.

I plan to write more blog posts, though some/most content will undoubtly be garbage. In the future I hope I can look back and see what I did during that particular year.

Foot injury

I got plantar fasciitis on my foot last month. Most likely it was effect of being overweight as well, apart from flat feet.
Now I don't run anymore, just exercise with rowing machine at home. Not sure if I will ever achieve 10 km run under 1 hour.

Covid-19

I am a home person generally, as I work remotely.
However it is stressful that I can't go around freely especially at weekend. I'd love to watch movie at cinema again or drink coffee while browsing / studying at coffee shop.

Life is full of unwanted events. Most can be attributed to my own failures.
Everything will be fine ....... hopefully.
I will try to fill this year with fabulous adventure in coding !
May God bless us and keep us strong everyday !

Life of My Raspi

July 5, 2016

3 years ago, I followed the hype, and bought a Raspberry Pi model B, without really using it.
Fast forward to today, I opened my cardboard box and found it again.

Vagrant Settings for VirtualBox Networking

June 20, 2016

Bad things happened, my fiber internet disconnected for several days and I had to use tethering. Unfortunately, my vagrant's virtual box network connection became very slow.

config.vm.provider "virtualbox" do |vb|
...
   vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
   vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
...
end  

Adding natdnshostresolver1 and natdnsproxy1 fixed the issue.

Detecting Document Width Early

June 17, 2016

I just had a situation where I need to put ad in different location for mobile view. The placement is hard to solve via CSS appproach.
So I had to do some width detection inside Google Publisher Tag (GPT) slot definition, which is executed early and async.
For some reason $(document).width() is not always evaluated.
It appears that jQuery approach is best used after document ready event, which is not suitable for my purpose.

Fortunately Modernizr's media query function works in my case

...
var isDesktopView = Modernizr.mq("screen and (min-width:970px)");
....

Using SQLite as Data Store In Unreal

May 30, 2016

We are researching for the best way to store dialogue data with Unreal.
The default approach for storing data in Unreal seems to be DataTable, which can be created by importing CSV file. However dialogue seems to be relational data, so we are wondering if the embedded databases like SQLite is a good way for storing data in Unreal.

Compiling SQLite as Static Library

As I was a desktop app developer, the first thing that comes to my mind is SQLite. The common way to include SQLite is by referencing it as static library. As there is no downloadable .lib, you will need to download the source code from https://www.sqlite.org.

If we compile the source code directly, it will seem to work. However once we try to execute SQLIte function in our project, we get "error C4703: potentially uninitialized local pointer variable used".
Thanks to this SO post, I managed to solve the issue. Basically, we need to add the following lines in sqlite.c

#pragma warning ( disable : 4703 )   

Including SQLite in Unreal Build System

First we will need to include header and .lib file in code directory.
For the time being, we use this directory structure

Root Project
    ...
    Third Party
        sqlite3
            Includes
                sqlite3.h
            Libs
                sqlite3-x64.lib
                sqlite3-x32.lib
    ...

Unreal uses Unreal Build Tools (UBT) for managing the build process.
UBT itself is C# based, and we will need to do build config in C#.
In every module, we will find module rules files, which use ModuleName.Build.cs as file name convention. We need to inform module rule that we will need to load SQLite

public MyProjectName(TargetInfo target)
{
    ....
    LoadSqlite(target);
}

private string ModulePath
{
    get 
    { 
        return ModuleDirectory;
    }
}

private string ThirdPartyPath
{
    get { return Path.GetFullPath(Path.Combine(ModulePath, "../../ThirdParty/")); }
}

public bool LoadSqlite(TargetInfo Target)
{
    bool isLibrarySupported = false;

    if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Win32))
    {
        isLibrarySupported = true;
        string PlatformString = (Target.Platform == UnrealTargetPlatform.Win64) ? "x64" : "x86";
        string LibrariesPath = Path.Combine(ThirdPartyPath, "sqlite3", "Libs");
        PublicAdditionalLibraries.Add(Path.Combine(LibrariesPath, "sqlite3-"+PlatformString+".lib"));
    }

    if (isLibrarySupported)
    {
        PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "sqlite3", "Includes"));
    }

    return isLibrarySupported;
}

The above code is based on Unreal wiki, adapted to version 4.12.

Packaging

One thing to note, is that database file need to be copied into package folder, and not included in PAK file. This can be done via specifying "Additional non-asset directories to copy" in packaging settings.

Conclusion

To be honest, we are still not 100% sure if we want to use SQLite. In our plan, we will just do read operation, so there won't be any lock issue. However SQLite is platform dependent, and we don't know if the code will be 100% compatible if we run it in other environment, like game consoles. For now, we will just refactor, so we can fallback to use DataTable if SQLite is not supported.