суббота, 21 января 2017 г.

Why I prefer longer class names even when namespace guarantees no name conflict

Suppose:

namespace Tutorial {
class CarnavalEventTutorial {...}
}


I keep Tutorial at end of class because 2 reasons:
a. you may keep some field with the same name, e.g.

public CarnavalEvent CarnavalEvent { get; private set; }

And you don't get name collision here. And no collision with class name too.

b. Suppose, that you can set that Tutorial as field of Unity component in editor. Unity editor wount show you namespaces, so you'll get 2 CarnavalEvent and can't diferentiate which one is Tutorial and which is not. More ugly example:

namespace Windows
{
    namespace Shop
    {
        public class Window : MonoBehaviour {}
    }
}

So, in Unity you'll see Window component and may decide that it's basic component. While it's not.

And one more bad thing, suppose you want to include that "Window" in code:


public class EventTracker {
private List<Window> windows;
private Windows.Shop.Window shopWindow; // you need that, again, to tell reader that it is ShopWindow. And to fix compiler error.
}

So, trying to make names short you make them longer instead :)

Minuses:
The price for that is longer names. But, again, that rule don't ask to include all the names from namespace. E.g.:

namespace Game {
namespace QuestParts {
namespace Tutorial {
class CarnavalEventGameQuestPartsTutorial {...} // not needed
}
}
}

Because, usually, you wount get CarnavalEventTutorial at different levels of namespaces.

So, the rule is: CONSIDER DUBLICATING NAME FROM ENCLOSING NAMESPACE IN CLASS NAME

вторник, 10 января 2017 г.

Collecting managed assert stack traces in release build of iOS Unity App

All below done with BuildOptions.ForceEnableAssertions, messages logged with NSLog or Console.WriteLine to be in release build (not just debug) Unity 5.5.0f3

Suppose client code:
Assert.IsFalse(true); // Unity's assert, not System

That stack we receive in Application.logMessageReceived callback:

1. UnityEngine.EventSystems.StandaloneInputModule:ProcessTouchPress(PointerEventData, Boolean, Boolean)

That message we see in Xcode console (it is made by Unity automatically)

2. some message guys
Assertion failed. Value was True
Expected: False
UnityEngine.Events.InvokableCallList:Invoke(Object[])
UnityEngine.EventSystems.ExecuteEvents:Execute(GameObject, BaseEventData, EventFunction`1)
UnityEngine.EventSystems.StandaloneInputModule:ProcessTouchPress(PointerEventData, Boolean, Boolean)

And that stack we get through new StackTrace(0, true) at the point of the call:

3. MyPanelBehaviour:OnClickA()
UnityEngine.Events.InvokableCallList:Invoke(Object[] parameters)
UnityEngine.EventSystems.ExecuteEvents:Execute(GameObject target, BaseEventData eventData, EventFunction`1 functor)
UnityEngine.EventSystems.StandaloneInputModule:ProcessTouchPress(PointerEventData pointerEvent, Boolean pressed, Boolean released)

You see, that new StackTrace(0, true) at the point of the call is most useful because only it contains OnClickA()*

So, to collect managed stack traces successfully we need to collect stack manually with new StackTrace.

Note: string StackTraceUtility.ExtractStackTrace() may be useful too. It uses new StackTrace(...) inside but additionally formats it to readable string in Unity stack style

Note: I've encountered on one of earlier versions of Unity bug. If you set in iOS player settings Logging from ScriptOnly to Full, you'll get "StackTrace is not supported on this platform" in Application.logMessageReceived callback instead of stack and no automatic message in Xcode console.

Hint: You also can get stack with new StackTrace() in Application.logMessageReceived. It will contain caller code (not just code that collects and dispatches log). I've tested it. And also, in documentation, it is said, that Application.logMessageReceived is allways called on the main thread (vs Application.logMessageReceivedThreaded) and that is the place where usually assertion happens.

* Note that, on earlier version of Unity I got OnClickA() in 2 too

понедельник, 1 августа 2016 г.

Contact

Send e-mail to vnms11@gmail.com

IZEng - engine for game development

IZEng is an open-source game engine with 2D graphics onboard. It encapsulates DirectX work. It includes simple movement models: linear, angular. Supports acceleration, friction, gravity if needed. RockCarrier is one of my games, which is developed on the base of this engine. Documentation included, but not full.

If you have questions, contact: vnms11@gmail.com. Title the letter "IgriZdes Engine".

I developed this small engine when I was studying in the University, so don't be surprised.
Source code with documentation on github  Download

понедельник, 4 июля 2016 г.

Building and running Android Studio gradle project on android device

Recently I was just checking out if AIDE team added support to build gradle-based projects. So, indeed they added:

AIDE also supports basic Android Studio projects, which follow the default project structure. The full gradle build system is not yet supported though
(source: http://www.android-ide.com/tutorial_androidstudio.html)

So, if your gradle setup is simple, you can just open your android project in AIDE and run.

But what to do if not? As before we have a workarond: create eclipse project files (.classpath + .project) for our project. AIDE works with eclipse project structure quite well. But what to do with the dependencies? It's insane to write all of them by hand. Likely, LibGdx enthusiasts gives us script which generates those strings for us (see for example eclipse task here)

I'll give details on example of how to build & run LibGdx gradle project in AIDE.

суббота, 30 апреля 2016 г.

MSI X99A SLI PLUS Windows 10 hang issue resolved

I've become a happy owner of MSI X99A Sli Plus mobo. I already read about many issues with asus burninng, msi burning, random Windows hangs due to problems with USB. And I want to say that I encountered nothing of that with my MSI mobo (bios 1.9, recently updated it to 1.B).

But I encountered an annoying hang for which I found a solution, so I want to share it because I don't see it anywhere on the web.

Problem: after unplugging PC from the outlet and plugging back Windows 10 hangs for the first time.
Solution: insert USB stick in one of the USB3.1 slots. You just need to keep 1 USB3.1 slot occupied to not run into that problem

четверг, 7 апреля 2016 г.

C#: Why Dictionary with hashcode as key is dangerous

Recently, I encountered following code:

        private readonly Dictionary<int, View> _listCellsForDisposal;
            if (!_listCellsForDisposal.Contains(view.GetHashCode()))
             {
                _listCellsForDisposal.Add(view.GetHashCode(), view);
             }

The intent of that code is just add item to the list if it doesn't present. But is it doing work well? It doesn't. Let's see why.

At first, let's look at the signature of GetHashCode:

public override int GetHashCode()

So, it returns int. int in c# is platform-dependent. For example int32 takes 4 bytes, it's range is:

-2,147,483,648 to 2,147,483,647

(source: https://msdn.microsoft.com/ru-ru/library/5kzh1b5w.aspx)

But how many objects can we add to the dictionary?