UnsafeMutablePointer usage in Swift 3 - uibezierpath

I am using the following extension for UIBezierPath:
extension UIBezierPath {
var elements: [PathElement] {
var pathElements = [PathElement]()
withUnsafeMutablePointer(&pathElements) { elementsPointer in
CGPathApply(CGPath, elementsPointer) { (userInfo, nextElementPointer) in
let nextElement = PathElement(element: nextElementPointer.memory)
let elementsPointer = UnsafeMutablePointer<[PathElement]>(userInfo)
elementsPointer.memory.append(nextElement)
}
}
return pathElements
}
}
This is from the site:
https://oleb.net/blog/2015/06/c-callbacks-in-swift/
However, this breaks with Swift 3 for the following line:
let elementsPointer = UnsafeMutablePointer<[PathElement]>(userInfo)
Following error is displayed:
Cannot invade initializer for type 'UnsafeMutablePointer<[PathElement]>' with an argument list of type '(UnsafeMutableRawPointer?)'
I understand that this is related to the change in Swift 3:UnsafeRawPointerMigration
https://swift.org/migration-guide/se-0107-migrate.html
However, I am not quite sure the best way to port this to Swift 3. Would you be able to provide some help in this regard w/ updated code for the above extension?

I reached out Ole Begemann directly regarding this question. He was very helpful and promptly provided updated code that works with Swift 3. Sharing the same if someone else runs into the same issue as well.
This should work:
extension UIBezierPath {
var elements: [PathElement] {
var pathElements = [PathElement]()
withUnsafeMutablePointer(to: &pathElements) { elementsPointer in
let rawElementsPointer = UnsafeMutableRawPointer(elementsPointer)
cgPath.apply(info: rawElementsPointer) { userInfo, nextElementPointer in
let nextElement = PathElement(element: nextElementPointer.pointee)
let elementsPointer = userInfo?.assumingMemoryBound(to: [PathElement].self)
elementsPointer?.pointee.append(nextElement)
}
}
return pathElements
}
}

Related

How toUppercase() one property of a list in kotlin with map?

I don't understand why the uppercase is not applied when return the data?
val userList: LiveData<List<UserData>> = Transformations.map(userRepository.getUsers()) { data ->
data.forEach {
it.name.toUpperCase()
Log.i("uppercase", it.name.toUpperCase()) //uppercase working here
}
Log.i("data", data.toString()) //uppercase not there
return#map data
}
val userList: LiveData<List<UserData>> = Transformations.map(userRepository.getUsers()) { data ->
data.forEach {
it.name = it.name.toUpperCase() //This is what you're missing, as explained by #forpas in the comment section.
Log.i("uppercase", it.name.toUpperCase()) //uppercase working here
}
Log.i("data", data.toString()) //uppercase now there
return#map data
}
Credit goes to #forpas since he answered first but did not just add it as an answer.

createImage() vs createImg() vs loadImage() in p5. which to use to load in an array of images for use in ml5?

I am attempting to piece together an example from ml5 on image style transfer (https://ml5js.org/docs/style-transfer-image-example) with p5.js examples parsing a JSON of image URLs, and adding them to an array to display as images. I am hitting a dead end as I do not think I fully understand the ways that p5 stores images in an array, nor do I fully understand the difference between createImg() createImage() or loadImage() (which one to use!!)
The goal is to use Bing image API to return a list of URLS from a search (this part is working fine) and run those images through a pretrained model (this part is working fine when just used on a local image). It is the bringing the two together that I am unable to figure out. Any suggestions or advice (is this even possible??!) greatly appreciated.
I have already tried loading images into an array and iterating through the array in the draw() function. The problem happens when I need to address an image in order to actually apply the style transfer model. It seems like my array is empty when I attempt to refer to it anywhere except draw(). I am sure I am thinking about this incorrectly.
var imageData;
let imgArray = [];
var w = (window.innerWidth)/3;
var h = (window.innerHeight)/4;
var index = 0;
var xPos = 0;
var yPos = 0;
var indexMax = 3;
let style;
let resultImg;
function preload() {
loadData();
}
function loadData(){
var url = api + search + subscriptionKey;
loadJSON(url, gotData);
}
function gotData(data) {
imageData = data;
for (var i=0; i < indexMax; i++){
_url = imageData.value[i].contentUrl;
imgArray.push(loadImage(_url));
}
function displayImages(){
if (index < 3){
index++;
} else {
index = 0;
};
function setup() {
createCanvas(1200, 800).parent('canvasContainer');
var button = select('#display');
button.mousePressed(displayImages);
var transferBtn = select('#transferBtn');
transferBtn.mousePressed(transferImages);
//create style method
style = ml5.styleTransfer('/model', modelLoaded);
}
function draw() {
image(imgArray[index], xPos, yPos, w, h);
}
//ml5 stuff
function modelLoaded() {
if (style.ready){
select('#status').html('Model Loaded');
//style.transfer(gotResult);
}
}
function transferImages(){
select('#status').html('applying style transfer');
style.transfer(tempImg, function(err, result){
createImg(result.src);
});
select('#status').html('done');
}
I am attempting to (unsuccessfully) create a "tempImg" from imgArray[0] to try to figure out where this createImage needs to go, but have not gotten this to work. I have CORS enabled, so I didnt think this was the problem, but am getting the following error. Please help me understand how to think about this differently.
You should use loadImage instead of createImg.
style.transfer(tempImg, function(err, result){
p5CompatibleImage = loadImage(result.src);
});

AndroidX itemTouchListener

I have just migrated a project to androidX and have managed to fix all teh issues except 1. which is the implimentation of the touch listener below.
private fun setItemTouchListner() {
val touchListner = object: ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
override fun onMove(recyclerView: androidx.recyclerview.widget.RecyclerView?, viewHolder: androidx.recyclerview.widget.RecyclerView.ViewHolder?, target: androidx.recyclerview.widget.RecyclerView.ViewHolder?): Boolean {
return false
}
override fun onSwiped(viewHolder: androidx.recyclerview.widget.RecyclerView.ViewHolder?, direction: Int) {
var rec: ChargeRecord? = null
if (viewHolder != null) {
rec = mAdapter?.getRecord((viewHolder.adapterPosition))
}
// delete record from cloud
if (rec != null) {
firebase?.child(rec.id)?.removeValue()
recordsViewModel?.deleteRecord(rec)
}
// remove record from list
if (viewHolder != null) {
records_list.adapter.notifyItemRemoved(viewHolder.adapterPosition)
}
}
}
val itemTouchHelper = ItemTouchHelper(touchListner)
itemTouchHelper.attachToRecyclerView(records_list)
}
I get an object is not abstract error and override does nothing error. I have searched around and tried to reformat the code but cant seem to fix it. Any guidance would be appreciated.
cheers
Ahhh
After alot of looking and pondering i finally worked out, i had to re-impliment the move and swipe methods.
this fixed the issue
cheers

Access one to many CoreData with predicate

I have an one-to-many database (Questions--->>Buttons)
I am stuck here as I don't know how to proceed with this to access the buttons from my database:
I have the following code that I can get to my Questions Entity but I don't know how to proceed from here. Thanks
func presentQuestionDetails(questionID :Int) {
let coreDataStack = CoreDataStack()
managedObjectContext = coreDataStack.persistentContainer.viewContext
let fetchRequest: NSFetchRequest<Questions> = Questions.fetchRequest()
let myPredicate = NSPredicate(format: "%K == %i", "questionID", questionID)
fetchRequest.predicate = myPredicate
do {
let results = try managedObjectContext!.fetch(fetchRequest)
if results.isEmpty {
//empty
print("empty")
}
else {
let question = results[0]
//do something
print("got something")
questionLabel.text = question.questionTitle
for _ in 0..<(question.buttons?.count)! {
//I'D LIKE TO LOOP THROUGH MY BUTTONS HERE AND ACCESS MY "buttonTitle" i.e print(buttons.buttonTitle!)
}
}
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
Would that be the correct way? I am only guessing and would like your input.
It seems to provide the right outcome but I am not sure if this is the right way to do it...
thanks
[...]
else {
let question = results[0]
//do something
print("got something")
questionLabel.text = question.questionTitle
let fetchRequest: NSFetchRequest<Buttons> = Buttons.fetchRequest()
let myPredicate = NSPredicate(format: "%K == %i", "questions", questionID)
fetchRequest.predicate = myPredicate
do {
let results = try managedObjectContext!.fetch(fetchRequest)
for buttons in results {
print(buttons.buttonTitle!)
}
}
catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}

How do I access Remoteobjects by using ActionScript?

This questions is discussed in many places, but none of the solutions seem to work for me. Heres the thing: In my mxml-code everything works perfectly:
<s:RemoteObject id="remotetest" destination="Hibernatetest" endpoint="http://praiseJESUS/blazeds/messagebroker/amf" result="remotetest_resultHandler(event)" fault="remotetest_faultHandler(event)"/>
<s:Button x="1248" y="401" label="Laden" click="remotetest.getCells()"/>
protected function remotetest_resultHandler(event:ResultEvent):void
{
var cellList:ArrayCollection = event.result as ArrayCollection;
}
Now, this works perfectly. What doesnt work on the other hand is this:
var ro:RemoteObject = new RemoteObject;
var cs:ChannelSet = new ChannelSet;
var c:Channel = new AMFChannel("my-amf","http://JESUSAGAIN/blazeds/messagebroker/amf");
cs.addChannel(c);
ro.channelSet = cs;
ro.destination = "MyClass";
ro.source = "myNamespace.MyClass";
ro.getOperation("myfunction()").send();
This SHOULD work - dunno why it doesnt. Any hints?
Upon inspecting the code of the RemoteObject, i found the following code snippet:
mx_internal function initEndpoint():void
{
if (endpoint != null)
{
var chan:Channel;
if (endpoint.indexOf("https") == 0)
{
chan = new SecureAMFChannel(null, endpoint);
}
else
{
chan = new AMFChannel(null, endpoint);
}
channelSet = new ChannelSet();
channelSet.addChannel(chan);
}
}
This shows, that if an endpoint is defined, the RemoteObject-Class will create its own channelset. Allthough it might seem that this is the same as what I did, i cannot be, for the following piece of code actually works, unlike my first attempt.
var ro:RemoteObject = new RemoteObject("Hibernatetest");
ro.endpoint = "http://Jesus/blazeds/messagebroker/amf";
ro.myfunction();
Its seems one has to take great care when one defines the channelset. Maybe someone can enlighten me regarding this matter.

Resources