I've got some kotlin navtive `stately` questions. ...
# multiplatform
s
I've got some kotlin navtive
stately
questions. So I have an object with two
IsolateState
fields and two setter functions:
Copy code
object FooIos {
	actual val fooList = IsolateState { mutableListOf<MyInterface>() }

    actual val fooString = IsolateState { DataClassWithVarStringField("") }

    actual fun setStringValue(fooStringValue: String) {
        fooString.access { it.varField = fooStringValue }
    }

    actual fun addMyInterfaceCollection(myInterfaceCollection: Collection<MyInterface>) {
        fooList.access { it }.addAll(myInterfaceCollection.toList())
    }

    actual fun doStuff() {
    	fooList.access { item -> 			// fooList is empty
            println("fooList item: $item")
        }

        explicitTag.access { objWithStr ->
            println("objWithStr: $objWithStr") // not empty...prints expected value
        }
    }
}
So far this seems to work. I set the values on the main thread and I can see that the fields are populated, however, later on when I try to use these, fooList is empty regardless of what thread I'm on. I've been trying a number of different things but for some reason I keep loosing the list. What am I missing? I haven't tried the stately collections yet. Second thing is when I try to access the stately field like
val strValue = fooString.access { it }
, it crashes. The exception is
FreezingException: freezing of Ok(result=DataClassWithVarStringField(varField=test)) has failed, first blocker is DataClassWithVarStringField(varField=test)
r
You should avoid doing things like
state.access { it }
. The way stately works is, the lambda you pass to
access {}
will always run on the same thread, so the state you handle in there (ie the
it
of the lambda) is safe to mutate. But whatever you return from there will be frozen so that it can be passed back to the calling thread. When you do
state.access { it }
that results in freezing the state which defeats the purpose of stately (and I believe it's disallowed with an
ensureNeverFrozen()
call which is generating the error message you see). For your list method, try something like
Copy code
fooList.access { it.addAll(myInterfaceCollection.toList()) }
Also note that most of this becomes less relevant once you're on the new memory model at which point you'll probably want to drop your isolatestate usage.
s
Copy code
fooList.access { it.addAll(myInterfaceCollection.toList()) }
ok so I think I've actually tried this before - I've been changing things up a lot so i think it was just an oversite - but corrected it and I still have the same issue where the list is empty. I had the new memory model enabled in another module - i forgot to enable it for this current module. I've enabled it now and will try to do things without stately.
m
Just a side note - why you do not use IsoCollections (it has a MutableList implementation) instead the blank IsolateState, so you can spare this access thingi?
s
tried an IsoMutableList but same thing. I got the new memory model stuff working but I'm still having an issue with the list getting cleared. I'm not making any calls to clear the list or remove any items, so I'm pretty confused about what's happening. I've tried other collection types, including some custom lists, plus wrapping the list in another class. why would the string value persist but not the list?
m
Super strange...never had this problem...is the project opensource/openaccess?
s
sorry I got pulled away from my kmp work....my project isn't open source but I made a test project that is pretty close to what I'm trying to do.: https://github.com/fluxxion82/kmp_test.git