https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
j

josephivie

02/05/2019, 4:47 PM
I'm going to introduce several projects I've been working on for multiplatform. https://github.com/lightningkite/kommon - A collection of random tidbits that really should be part of the standard library https://github.com/lightningkite/reacktive - An observable property and signaling system for multiplatform, used in an upcoming UI library https://github.com/lightningkite/lokalize - A library for accessing locale information All are available through a specific JCenter repository as specified in the READMEs! I'd be happy to get PRs and any other help too.
🎉 3
a

altavir

02/05/2019, 5:17 PM
I think you should join efforts with @Lamberto Basti and his https://github.com/lamba92/kotlin-extlib. It is better to have one good library. And I like his naming better.
j

josephivie

02/05/2019, 5:18 PM
I agree - I was not aware of the project. That only applies to Kommon, though.
a

altavir

02/05/2019, 5:21 PM
as for reaktive, I saw a few libraries with similar functionaliry. Maybe not completely the same. Still, what would definitely be usefull is a cross-platform implementation for JavaFX properties and bindings. There are few ideas about moving tornadoFX to multiplatform.
j

josephivie

02/05/2019, 5:22 PM
I've already finished the multiplatform GUI library and I'm cleaning up the build scripts.
a

altavir

02/05/2019, 5:22 PM
What do you use as jvm back-end?
j

josephivie

02/05/2019, 5:23 PM
JavaFX, though I'd be happy to change it - its performance isn't spectacular
iOS isn't finished yet, but JS, JavaFX, and Android all work great.
Material design by default, customizeable per platform.
👍 1
a

altavir

02/05/2019, 5:24 PM
do you have code samples for it or it is proprietary?
j

josephivie

02/05/2019, 5:25 PM
It's open source right now, it's just not building due to some changes I made in the libraries above for the sake of making them ready to make public. https://github.com/lightningkite/koolui
l

Lamberto Basti

02/05/2019, 5:26 PM
In that case my GitHub page is not a proper repo. If you'd like to merge all the stuff we can create a new organization on GitHub. I can handle that if you want to merge :)
j

josephivie

02/05/2019, 5:26 PM
Take a look at
ViewFactory
to get a sense of how it works. For simplicity of API, all interactions with views are done strictly at creation time and afterwards through observable properties.
Sounds fantastic! Do you have CI? We'll need to get that set up to prevent it from being a pain. Also, I'm currently working on a Gradle plugin to simplify the Gradle scripts if we want to use that - give me a few days and it will be ready.
a

altavir

02/05/2019, 5:29 PM
@josephivie Have you seen tornado API. It is not ideal, but I like their lambda approach much better.
j

josephivie

02/05/2019, 5:30 PM
I use Anko on a regular basis. There's a couple extension functions available in the library already for writing it in lambda format.
l

Lamberto Basti

02/05/2019, 5:37 PM
@josephivie I have little experience with CI. I used only Travis but I guess you are more experienced than me. Have a look at my Gradle script https://bit.ly/2GnyXeU I think it works great for every K/N backend. I have no Mac so building, testing and publishing for Apple platforms is up to you. Is it even possible to CI using MacOS?
j

josephivie

02/05/2019, 5:41 PM
It is, but you have to actually contact people. I don't have a ton of experience with CI either, actually. That Gradle script is pretty similar to what I was doing before - my goal with this new plugin is to: - Have targets selected automatically based on the limitations of the dependencies - Declare the same dependency for each platform in one place - Simplify POM declaration
l

Lamberto Basti

02/05/2019, 5:44 PM
What do you mean by "Have targets selected automatically based on the limitations of the dependencies"? If i understood well, the other 2 points are already taken care of in my script. If you want you can join me on Discord here so we can talk instead of writing https://discord.gg/BU66x (link valid for 6h, 5 spots)
j

josephivie

02/05/2019, 6:05 PM
I'd rather keep it on here so that others interested in Kotlin could see our conversation - maybe they'll have something to add! I'll show you an example in just a sec - mind that there's still a lot of refining to do
👍 1
Copy code
kotlin {
    this.setup(project, KDependency.SourceSet("common",
            KDependencySet.standardLibrary,
            KDependencySet.testing,
            KDependencySet.testingAnnotations,
            KDependencySet.sourceSets("actuals",
                    KTargetSet.nonNative.sourceSet(
                            KDependencySet.sourceSets("nonNativeActuals",
                                    KTarget.js.sourceSet(),
                                    KTargetSet.jvmCommon.sourceSet()
                            )
                    ),
                    KTargetSet.native.sourceSet()
            )
    ))
}
Which can be read as: I have a source set called
common
which requires that the underlying platform have the standard library, testing library, and testing annotations. It also depends on some actuals being present in the library, which are split up into
native
for all native targets, and
nonNative
which has some implementations, but also needs
js
and
jvmCommon
to have all of the actuals.
The target platforms are determined by the dependencies - if the dependencies don't support
mingwx64
, for example, then it is not targeted.
The idea is that if my library was dependent on KotlinX Serialization, and they decided to start supporting Android Native, then my library would start supporting Android Native as well, with no changes from me.
It's too wordy right now, though, so I still have lots to figure out.
l

Lamberto Basti

02/05/2019, 6:16 PM
Could you draw a graph?
j

josephivie

02/05/2019, 6:21 PM
That's the idea - you define what any given source set depends on, and from there, the target platforms are determined.
Instead of saying what your goal is, you say what you have. Thus, you can guarantee that your code reaches as many platforms as possible without specifically stating each platform.
l

Lamberto Basti

02/05/2019, 6:25 PM
You mean if a new K/N target pops out in the future the script adapts without changing anything?
j

josephivie

02/05/2019, 6:25 PM
That's correct.
l

Lamberto Basti

02/05/2019, 6:26 PM
in my script just add in the list of targets it and it will adapt
at the moment every native target added will ereditate the source sets of the commonNative source set
j

josephivie

02/05/2019, 6:27 PM
True, and the idea of this plugin is to make deploying to all targets possible the default, rather than needing to specify it.
l

Lamberto Basti

02/05/2019, 6:27 PM
See, if JB decides to support PowerPC (lolwut) just add
powerPc()
ad the beginning of the script and the configure blocks will handle it.
well ofc if there is a cinterop you have to add stuff
j

josephivie

02/05/2019, 6:28 PM
Well of course
You're right, I'm just trying to make it so the declaration of all platforms is implicit and dependencies are grouped together by what they are, rather than their target platform.
l

Lamberto Basti

02/05/2019, 6:30 PM
the automatizable has been already automatized in my script! notice that this approach will cut out IntelliJ autocompletitition since it does not know which K/N target you are when writing down commonNative
j

josephivie

02/05/2019, 6:31 PM
When you start having a lot of dependencies in MPP, it starts getting really repetitive to add a copy of the dependency for each platform
l

Lamberto Basti

02/05/2019, 6:31 PM
Have a look here https://bit.ly/2DaDkGU
well if you look at my code, even the C code is written only one time xD
for the locks
j

josephivie

02/05/2019, 6:31 PM
That makes a lot of sense - I like that
👍 1
l

Lamberto Basti

02/05/2019, 6:31 PM
the configure lambda handles that
still, IntelliJ missing autocompletition is a big slowdown i assure you. but assuming we are primarily writing in the common sources it is handlable
j

josephivie

02/05/2019, 7:05 PM
For what we'd be doing together, your script has everything we need and it is really well built, but I've been working with a large set of MP dependencies in other projects. As such, I had to write
api 'some:path-platform:version'
for every single platform. It got really tedious. Also, sometimes things like KotlinX serialization wouldn't have implementations for some platforms, and so if I declared all the platforms, I'd end up with errors. That's the idea behind what I'm doing. I'm trying to make it look like this:
Copy code
setup(project) {
    requiresStandardLibrary()
    requiresTesting()
    requiresTestingAnnotations()

    //pulls in group:artifact-platform:version for each platform
    requiresMaven("group", "artifact", "version") {

        //You can override individual targets like this
        override(Targets.native, "group-artifact-native-special", "version")

        //If there is no dependency for a particular target, you can use this:
        notAvailable(Targets.androidNativeX64)
        //This will remove the given target from your list of publishing targets, but will allow you to use the others.
    }

    sourceSets {
        Targets.native.sourceSet {
            requiresMaven("group", "artifact-for-native", "version")
        }
        Targets.jvmCommon.sourceSet {

        }
        Targets.js.sourceSet {
            requiresMaven("group", "artifact-for-js", "version")
        }
    }
}
Sorry I'm not doing very well at articulating myself
Don't bother with my plugin for this project in particular, but I'm still building the plugin
@Lamberto Basti Let me know when you have an org/repo up and I'll make a PR into it
l

Lamberto Basti

02/05/2019, 7:29 PM
I get what you mean, you can do it easily as well with the configure lambda, no need for a separeted plugin. Yeah I agree, we'll have a look later. Btw keep in mind that kotlinx libs make use of Gradle metadata, have a look here https://bit.ly/2RGs4r8
j

josephivie

02/05/2019, 7:32 PM
Sounds good!
l

Lamberto Basti

02/05/2019, 7:36 PM
The lib has been actually moved here 🙂 https://github.com/kotlin-extra-library/kotlin-extlib
@altavir change the remote if you already forked it!
Now i need to figure out how to reserve the domain org.extra.kotlin
r

Robert

02/05/2019, 8:46 PM
I like (and use) the lokalize library. Please be aware there's some dupicated functionality with https://github.com/korlibs/klock by @Deactivated User, idk if it is possible to somehow make the two compatible? 😏
j

josephivie

02/05/2019, 8:55 PM
Correct, that is purposeful for now. Klock has nothing for representing time alone and date alone, which is critical to the (soon to be released) libraries that depend on it. I'd like to submit some PRs for Klock, but I don't have a lot of time and I'm still working like a madman on releasing what I already have. In the future, it's quite likely Lokalize will use Klock.
👍 1
💪 1
r

Robert

02/05/2019, 9:23 PM
That's really awesome