Merge classes

For example I do define something like DeviceInfo.mc in my resource folders. This file contains device name, font variables and should contain watchface specific stuff as well.

So my setup would look like following:

  • 1 - shared/src-fenix5/DeviceInfo.mc
  • 2 - shared/src-fenix5s/DeviceInfo.mc
  • 3 - shared/src-fonts-fenix5/DeviceInfo.mc
  • ...

And now I'd like to use 1 + 3 for fenix 5 devices and 2 + 3 for fenix 5s devices and similar. This does not work, because alle DeviceInfos.mc files to contain the same class.

Solution

Currently I do use different class names (DeviceInfo + DeviceFontInfo) but I'd prefer to avoid such minimal classes (they only contain a few constants)

Question

I'd like to have ONE info class that merges all contents from different folders, is that somehow possible? Actually in general, I'd need something like a namespace instead of a class, because my info class only contains static definitions and no real class code.

  • What does your jungle file look like?

    In one case I have

    source

    source-maps

    source-nomaps

    and a simple thing like this in the jungles file.  Same class in both maps and no-maps

    srcBase=source
    resBase=resources
    
    #maps Stuff
    base.sourcePath=$(srcBase);source-nomaps
    base.resourcePath=$(resBase)
    
    # tested with maps
    fenix5x.sourcePath = $(srcBase);source-maps
    fenix5x.resourcePath = $(resBase);resources-maps
    
    
    (and so on)

  • My jungles file looks like following:

    srcBase=source;../shared-src-core;../shared-src-data/source
    
    fenix5xplus.sourcePath = $(srcBase);../shared-src-devices/source-fenix5x
    fenix5xplus.resourcePath=$(resBase)
    fenix5plus.sourcePath = $(srcBase);../shared-src-devices/source-fenix5
    fenix5plus.resourcePath=$(resBase)
    fenix5splus.sourcePath = $(srcBase);../shared-src-devices/source-fenix5s
    fenix5splus.resourcePath=$(resBase)

    Any my source-fenix5x contains following DeviceInfo.mc (and similar files for other devices):

    using Toybox.Graphics;
    
    class DeviceInfo {
    
    	static const MODEL = 4 /* Fenix 5X */;
    	static const DEVICE_NAME = "Fenix 5X";
    	
    	// Hilfe für Font-Sizes:
    	// https://developer.garmin.com/connect-iq/reference-guides/devices-reference/
    	// => auf Device klicken, da gibt es eine Tabelle mit Schriftarten
    	// => man muss trotzdem mit dem Font Tester probieren!
    	
    	static const FONT_MINI = new Font(null, 12, 4, 0).setRez(Rez.Fonts.custom_small);
    	//static const FONT_MINI = new Font(Graphics.FONT_XTINY, 17, 1, 0); // 26 | ROBOTO_26PX
    	static const FONT_SMALL = new Font(Graphics.FONT_TINY, 17, 1, 0); // 26 | ROBOTO_26PX
    	static const FONT_MEDIUM = new Font(Graphics.FONT_MEDIUM, 21, 1, 0); // 29 | ROBOTO_34PX
    
    	static const FONT_TIME_SMALL = new Font(Graphics.FONT_NUMBER_MILD, 26, 0, 2); // 26 | CHRONOS 26PX
    	static const FONT_TIME_MEDIUM = new Font(Graphics.FONT_NUMBER_MEDIUM, 36, 0, 0); // 36 | CHRONOS 36PX
    	static const FONT_TIME_LARGE = new Font(Graphics.FONT_NUMBER_HOT, 52, 0, 0); // 52 | CHRONOS 52PX
    }

    What I want to have is following:

    // File: ../shared-src-fonts-roboto-26-26-29/DeviceInfo.mc
    class DeviceInfo {
    	static const FONT_MINI = new Font(null, 12, 4, 0).setRez(Rez.Fonts.custom_small);
    	static const FONT_SMALL = new Font(Graphics.FONT_TINY, 17, 1, 0); // 26 | ROBOTO_26PX
    	static const FONT_MEDIUM = new Font(Graphics.FONT_MEDIUM, 21, 1, 0); // 29 | ROBOTO_34PX
    }
    
    // File: ../shared-src-fonts-time-chronos-26-36-52/DeviceInfo.mc
    class DeviceInfo {
    	static const FONT_TIME_SMALL = new Font(Graphics.FONT_NUMBER_MILD, 26, 0, 2); // 26 | CHRONOS 26PX
    	static const FONT_TIME_MEDIUM = new Font(Graphics.FONT_NUMBER_MEDIUM, 36, 0, 0); // 36 | CHRONOS 36PX
    	static const FONT_TIME_LARGE = new Font(Graphics.FONT_NUMBER_HOT, 52, 0, 0); // 52 | CHRONOS 52PX
    }
    
    // File: ../shared-src-devices-fenix5x/DeviceInfo.mc
    class DeviceInfo {
    	static const MODEL = 4 /* Fenix 5X */;
    	static const DEVICE_NAME = "Fenix 5X";
    }
    
    // monkey.jungle
    fenix5xplus.sourcePath = $(srcBase);../shared-src-fonts-roboto-26-26-29;../shared-src-fonts-time-chronos-26-36-52;../shared-src-devices-fenix5x
    fenix5xplus.resourcePath=$(resBase)

    Why? Because I want to reuse smaller definitions and I want to have all shared definitions in a single class (DeviceInfo in my case - this acutally just serves as a namespace) to don't waste resources for too many small classes and for usability, it's easier to use DeviceInfo.<VALUE> instead of thinking about which value is defined in which class

  • You're on the right track but there is something I'm not seeing here.

    With my maps and no-maps folders, both have a maps.mc file with the same class:

    class HikeChart {

  • You are including HikeChart only once for each device, I would like to include different versions of DeviceInfo for each device. My logic needs class merging, like resources are merged e.g.

    I can solve this be using different class names, but that overcomplicates the usage... Check my last code block, I want to include ALL 3 DeviceInfo classes (they all have the same name) for one device - this will lead to duplicate class errors. I want to use the class as namespace only

  • You can't merge classes (or functions, or anything else like that), but you can use my janky conditional compilation solution to do accomplish what you are looking for.

    Or even more simply, you could use simple annotation excludes and duplicate the same code multiple times (which you probably don't want to do.)

    forums.garmin.com/.../solution-for-line-by-line-mc-conditional-compilation

  • Another way to do it would be to have annotations for each individual variable. (But you will probably have to declare the each variable multiple times -- once per annotation -- unless you want to use :has all over the place.)

  • Thanks for the ideas, but if there is no good alternative I may stay with my single file per device and duplicate definitions in all those files...

    Only useable alternative may be class less files with static const definitions in the global namespace, but this does really not look good and I have not tested if this is possible yet