Comms in monkey.barrels?

I'm experimenting with monkey.barrels and getting an error when accessing Communications.

using Toybox.Communications as Comms;
...
Comms.makeWebRequest(
url,
params,
{ :headers => headers,
:method =>Comms.HTTP_REQUEST_METHOD_POST,
:responseType => Comms.HTTP_RESPONSE_CONTENT_TYPE_JSON
},
method(:sendLogsCallback)
) ;


Code obviously works fine in original build, but when I put it in barrels it fails at runtime with
Symbol Not Found Error
in sendLogs (/private/var/folders/ly/qnh242bx7z98fz51w0yvjvjm0000gn/T/sharedCode-0.0.0.barrel13810905824211180534/content/sharedCode.mc:123)

Line 123 is Comms.makeWebRequest.
Is there a limitation I'm missing?

  • Unfortunately the forum refuses to accept my response which it happily previews but fails to post with a JSON error.

    I can't really read the text in the image you posted, but I'm assuming that you were unable to get either one of the techniques I suggested to work. Here is an implementation of the second technique I suggested.

    using Toybox.Application;
    using Toybox.Communications;
    using Toybox.System;
    using Toybox.Lang;

    function a_global_function(code, data) {
    System.println(code);
    System.println(data);
    }

    class ComplexApp extends Application.AppBase {

    function initialize() {
    AppBase.initialize();

    Communications.makeWebRequest(
    "jsonplaceholder.typicode.com/.../115",
    {}, { "Content-Type" => Communications.REQUEST_CONTENT_TYPE_URL_ENCODED },
    new Lang.Method($, :a_global_function) // method(:onReceive)
    );
    }

    function getInitialView() {
    return [ new ComplexView() ];
    }
    }

  • In order to do my first suggestion, you need to create a class..

    class MyLogSender
    {
    function initialize() {
    }

    function sendLogs() {
    Communications.makeWebRequest(
    "jsonplaceholder.typicode.com/.../115",
    {}, { "Content-Type" => Communications.REQUEST_CONTENT_TYPE_URL_ENCODED },
    method(:onReceive)
    );
    }

    function onReceive(code, data) {
    System.println(code);
    System.println(data);
    }
    }
  • RaceQs I happen to use links in Eclipse to share code between different "clones" of the same app. Most of the codebase is the same, while there are a few resources that differ (and obviously, manifest.xml).

    I'm not saying this is the best way to do things, but this is how I did it.

    Say I have two projects, MyApp1 and MyApp2, which need to share some "library code" which we'll place in a folder MyApp.lib. I'll assume all 3 folders are in a common parent folder (say, MyApp)

    1) Decide what will be shared and where it will go.
    e.g.
    PROJECT_ROOT/shared.jungle
    PROJECT_ROOT/shared/resources
    PROJECT_ROOT/shared/source

    2) For MyApp1 and MyApp2, create the appropriate links in Eclipse to MyApp.lib.
    (Right click project folder > New > File/Folder > Advanced > Link to alternate location)
    PROJECT_ROOT/shared.jungle => ../MyApp.lib/shared.jungle
    PROJECT_ROOT/shared/=> ../MyApp.lib/shared/

    As Jim mentioned, you could also create symbolic links in the filesystem, but this has the disadvantage of not being portable across operating systems, filesystems, archives, etc, although there are other advantages.

    3) In shared.jungle, set up the paths for your shared resources:
    base.sourcePath = $(base.sourcePath);shared/source
    base.resourcePath = $(base.resourcePath);shared/resources


    4) Simply place all your shared resources and shared source files in the appropriate locations. Add any shared build configuration to shared.jungle.

    IMO, your choice of module, class or global functions/variables should not be based on whether you are copying-and-pasting the code manually or whether you are sharing the code in this manner. Just do what you would've done in the first place, since the compiler doesn't care how you duplicated the code. (Of course there's code size overhead for classes and even modules, but then there's performance penalties for using global symbols, which can be overcome with the $ operator.) There's even overhead for putting things in different source files (if I'm not mistaken), so you will have to decide for yourself how you balance maintainability, code size and performance.
  • In order to do my first suggestion, you need to create a class..



    Interesting, that's exactly the pattern I deduced from your earlier advice which followed but it fails at runtime with:
    Failed invoking <symbol>

    Invalid Value

    Which in itself is not very informative!

    So for the moment I'm putting barrels on the back burner and putting up withe the fact that I'll have to maintain two sets of code.

    The suggestions for using links all looks like a complex kluge which I'm not keen to pursue.


  • Links aren't really that bad. (if you aren't using jungles)

    Let's say you already have a barrel project called "MyBarrel". and in it is the shared code. (thecode.mc)

    Your project is "MyApp". In MyApp, you could use the MyBarrel barrel, but with a link, you just go to MyApp/source, right click, new>file>advanced, then check "link to file in the file system". Then browse for MyBarrel/thecode.mc.

    When you build MyApp, it uses thecode.mc You could set up a link to the same way in MyApp2, so common code, no barrel actually used.
  • If by "kludge" you mean, "using links in Eclipse (or in the file system) gives me exactly what I need to share source code/resources with zero overhead", sure. IMO, it's a perfectly legitimate way to share resources (internally). Eclipse has links for a reason and Monkey C allows you to set the resources/source path for a reason, too. If you have both projects open and you change shared source code, both projects will build seamlessly. Once you've set everything up, you can forget about it completely. (Except that you may not want to have both projects open all the time, since you'll be building twice as much every time you save, if you have auto builds on.)

    Or you could use barrels and accept that there'll be overhead.

    Also, this is just a preference, but I would go with the "shared" folder method myself (instead of linking directly to files), as it allows you add as many shared files and folders as you want in the future without making more links (i.e. annoying kludges). It's especially useful for resources. Plus it gives you another way (other than the little link icon) to see very clearly what's shared in your project, because everything except the shared jungle file (if applicable) is in a different part of the hierarchy with an obvious name such as "shared".

    TL;DR:
    1) Link to one shared folder and one shared jungle file in each project
    2) Change your source/resource paths once (in your shared jungle)

    And that's it, forever. You can add as many shared source and resource files to that folder as you want, and you will never have to create another link.

    I mean, it can be an annoying kludge if you want it to be (e.g. share 50 files with 50 links). Or you could do it in a way where you set it up once and never worry about it again.
  • Interesting, that's exactly the pattern I deduced from your earlier advice which followed but it fails at runtime with:
    Failed invoking <symbol>
    Invalid Value

    Which in itself is not very informative!

    Agreed. Unfortunately, I can't reproduce the issue you're seeing, so I'd need a test case to work from.

  • RaceQs I happen to use links in Eclipse

    Seems Links don't work on my platform. Mac Mojave, Eclipse Oxygen, SDK 3.0.5
    And the Forum won't accept my post,

  • Or allow me to edit my post to add a link to my screenshot in Google Drive
  • RaceQs did you add the shared source location to your jungle file? e.g.
    base.sourcePath = $(base.sourcePath);shared/source
    base.resourcePath = $(base.resourcePath);shared/resources


    I guess this would be a good time to point out that Jim's way (direct link to a single source file rather than a whole folder) is better if you only ever intend on sharing one file. Then you don't need to worry about your jungle config.

    The way I described is good if you want to share multiple source files and resources (perhaps looking to the future). But admittedly it's probably too many steps if you only want to share one file. Sorry about that. Sometimes I tend to favour generic solutions even if they take a bit more work....