0

I have hit a wall with this one and I can't find any question with a solution for this here in SO.

I am using a PagingAdapter method, from Google's Paging library, that receives an inline function as a listener:

    fun addLoadStateListener(listener: (CombinedLoadStates) -> Unit) {
        differ.addLoadStateListener(listener)
    }

And then to remove the listener they provide the following method

    fun removeLoadStateListener(listener: (CombinedLoadStates) -> Unit) {
        differ.removeLoadStateListener(listener)
    }

And I am using it like this

myPagingAdapter.addLoadStateListener { it: CombinedLoadStates -> 
    myPagingAdapter.removeLoadStateListener(this)
}

I know the above does not work, but it worked when the file was written in java since it had a correct reference to itself inside its own function. However, in Kotlin I cannot find a way to do this at all. I tried turning into an anonymous function, but it still won't pass the correct context

myPagingAdapter.addLoadStateListener { fun(it: CombinedLoadStates) -> 
    myPagingAdapter.removeLoadStateListener(this)
}

At this point I have no idea how I can remove an inline function that can't reference itself, and I cannot find any documentation with a solution for this anywhere.

How can I remove in kotlin an inline function by referencing itself?

Shadow
  • 4,168
  • 5
  • 41
  • 72
  • 1
    It’s not an inline function. It’s a functional reference parameter. An inline function is one marked `inline`, which means the compiled code transfers its contents to the call site, usually to either enable reified generics or to avoid a functional object allocation for a functional reference parameter. A parameter is never inline, but it can be inlined if it is the parameter of an inline function. – Tenfour04 Sep 24 '21 at 04:38

2 Answers2

4

If I understand correctly, you need a reference of inline function which was passed in addLoadStateListener so you can pass in removeLoadStateListener. You can try this

myPagingAdapter.addLoadStateListener(object :  (String) -> Unit {
        override fun invoke(p1: String) {
            myPagingAdapter.removeLoadStateListener(this)
        }

    })
iamanbansal
  • 2,412
  • 2
  • 12
  • 20
1

You can create a local function to reference itself:

fun myFun(CombinedLoadStates): Unit {
    myPagingAdapter.removeLoadStateListener(::myFun)
}

myPagingAdapter.addLoadStateListener(::myFun)
F43nd1r
  • 7,690
  • 3
  • 24
  • 62
  • The goal is for the inline function to be able to reference itself so it can remove it when it needs to. Your suggestion does not solve my problem. If I want to do `myPagingAdapter.removeLoadStateListener(myFun)` inside the `doThings()` it will not work. – Shadow Sep 23 '21 at 21:25
  • ah, in this case you need a referencable function, see edit. – F43nd1r Sep 23 '21 at 21:38
  • it does not work. by the time the remove call is executed (an arbitrary time) the reference of that function is no longer the same as it was when it was added, unless I declare that function inside the function where the add listener call is being made. What I really need is for it to reference its own instance, otherwise it does not work correctly. – Shadow Sep 23 '21 at 22:38
  • @Shadow it seems to work fine even if it's not a local function: https://pl.kotl.in/QHb3wczwJ What exactly is your problem with this solution? It does reference itself here. – Joffrey Sep 23 '21 at 23:13
  • @Joffrey correct, your scenario in which the instance where `fun myListenerFun` is instantiated will work, the issue is when that instance is no longer the same, but does have a reference to `val listeners` still. In your example they are both tied to the same instance, but in my case they are not. – Shadow Sep 24 '21 at 14:22
  • @Shadow a top level `fun` is not instantiated, all references to it will point to the same object. Could you please share some minimal code that does not work using the above technique? I'm quite surprised – Joffrey Sep 24 '21 at 16:47
  • @Shadow here is what I thought you meant, and it still works: https://pl.kotl.in/q5kds2R7Q – Joffrey Sep 24 '21 at 16:54
  • Hey @F43nd1r can you know how to solve this [issue](https://stackoverflow.com/q/69755212/11560810) – Kotlin Learner Oct 28 '21 at 14:04