GithubHelp home page GithubHelp logo

Comments (9)

hfossli avatar hfossli commented on July 30, 2024

I've been having troubles with stay's myself - so I try to avoid them. I would rather have some constraints added and removed.

from rhea.

pschuster avatar pschuster commented on July 30, 2024

Thank you for your answer. I tried implementing it with constraints, the same result. But, I have found the error. I changed solver to be a pointer (heap instead of stack) and this works:

//
//  AFRheaTestView.m
//  FlexSchematics
//
//  Created by Phillip Schuster on 18.11.15.
//  Copyright © 2015 Appfruits. All rights reserved.
//

#import "AFRheaTestView.h"

#include "rhea/simplex_solver.hpp"
#include "rhea/iostream.hpp"
#include "rhea/variable.hpp"

@interface AFRheaTestView ()
@property (nonatomic, strong) NSTrackingArea* trackingArea;
@property (nonatomic, assign) BOOL dragged;
@property (nonatomic, assign) rhea::variable l1X;
@property (nonatomic, assign) rhea::variable l1Y;
@property (nonatomic, assign) rhea::variable r1X;
@property (nonatomic, assign) rhea::variable r1Y;
@property (nonatomic, assign) rhea::simplex_solver* solver;   // <!----- This is the relevant change!
@property (nonatomic, assign) rhea::constraint l1XC;
@property (nonatomic, assign) rhea::constraint l1YC;

@end

@implementation AFRheaTestView

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];

    // Drawing code here.
    [[NSColor magentaColor] setStroke];
    NSBezierPath* bezierPath = [NSBezierPath bezierPath];
    [bezierPath moveToPoint:NSMakePoint(self.l1X.value(), self.l1Y.value())];
    [bezierPath lineToPoint:NSMakePoint(self.r1X.value(), self.r1Y.value())];
    [bezierPath stroke];
}

-(void)awakeFromNib
{
//  self.l1X.set_value(100);
//  self.l1Y.set_value(100);

    self.solver = new rhea::simplex_solver();    // <!---- And this of course ;-)

    self.solver->set_autosolve(false);

    self.solver->on_resolve = [self](rhea::simplex_solver &solver) {
        std::cout << "on_resolve" << std::endl;
    };

    self.solver->on_variable_change = [self](const rhea::variable& v, rhea::simplex_solver& s) {
        std::cout << "on_variable_change " << v.value() << std::endl;
    };

    self.solver->add_stay(_l1X);
    self.solver->add_stay(_l1Y);

    self.solver->add_constraint(_r1X == _l1X + 100);
    self.solver->add_constraint(_r1Y == _l1Y + 100);
    self.solver->solve();

    NSTrackingAreaOptions options = (NSTrackingActiveAlways | NSTrackingInVisibleRect |
                                     NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved);
    self.trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds options:options owner:self userInfo:nil];
    [self addTrackingArea:self.trackingArea];
}

-(void)updateTrackingAreas
{
    [self removeTrackingArea:self.trackingArea];
    NSTrackingAreaOptions options = (NSTrackingActiveAlways | NSTrackingInVisibleRect |
                                     NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved);
    self.trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds options:options owner:self userInfo:nil];
    [self addTrackingArea:self.trackingArea];
}

-(void)mouseMoved:(NSEvent *)theEvent
{
    CGPoint curPoint = [self convertPoint:[theEvent locationInWindow] fromView:nil];

    self.solver->suggest(_l1X,curPoint.x);
    self.solver->suggest(_l1Y,curPoint.y);

    self.solver->solve();

    [self setNeedsDisplay:YES];
}

@end

Anyone has an explanation for that? As you can see I am using rhea in Objective-C++...

from rhea.

hfossli avatar hfossli commented on July 30, 2024

Using properties means calling methods which returns a new solver unless you use the pointer. So, that wasn't working for me as well. I have an obj-c facade around the solver for various reasons. The way I access the solver is by using the ivar directly.

@implementation ALEConstraintSolver {
    rhea::simplex_solver _solver;
}

from rhea.

hfossli avatar hfossli commented on July 30, 2024

Glad to hear you got it working btw. It is not trivial to use rhea from obj-c with wrt pointers and friends.

from rhea.

Nocte- avatar Nocte- commented on July 30, 2024

I have no Obj-C(++) experience myself, so if you guys have any suggestions how to make it easier to use I'd love to hear it.

from rhea.

hfossli avatar hfossli commented on July 30, 2024

Maybe a "best practices for rhea in obj-c" guide would be sufficient. What makes it hard is that the memory system is different from what we are used to. Some notes about how to pass around objects like simplex_solver, constraint_list, and variables would be to great help.

from rhea.

Nocte- avatar Nocte- commented on July 30, 2024

And by "memory system" you mean the way C++ handles memory in general? Or is there anything in Rhea in particular that could trip up Obj-C++ users? (Simplex_solver is quite normal, but constraints and variables are reference counted under the hood, perhaps that could lead to surprises.)

In any case, some guidelines or even just a small bit of example code would be nice to have in the documentation.

from rhea.

pschuster avatar pschuster commented on July 30, 2024

I can give a few guidelines. Adding rhea to an Objective-C Xcode project generates compiler/linker errors. There are a few things that should be done in order to get it compiled. I added the rhea files directly to my project with "Add files to project".

Then you have to change the Build Settings by clicking on the Project file in the Project Explorer (left side of Xcode). I changed the settings both in the Project Settings, as well at the Target to these settings from "GNU..." to these:

bildschirmfoto 2015-11-19 um 15 51 42

After that, you will have to rename all .m files to .mm. As you have to integrate C++ into Objective-C you will need to mark the files as Objective-C++ files. This is done by renaming them to .mm files. I did that for every file in the project and for every file that is later added. The only file I kept is main.m, as renaming that to .mm gave me strange errors. Getting strange compiler errors always makes me check that I really named all files with .mm, and most of the time I find a new class I added with .m name. Due the caching of Build Objects these errors sometimes come suddenly without context. As said before, check for .m files.

Another very important aspect is, that the solver must be a pointer and initialized via a "new rhea::simplex_solver". Of course a "delete ..." should remove this instance later down the road, i.e. in -dealloc for example.

Adding a property to a class:

@interface XYZ
@property (nonatomic, assign) rhea::simplex_solver* solver; 
@end

After that you will have to initialize it (i.e. in the init method):

-(instancetype)init
{
    self = [super init];
    if (self)
    {
        self.solver = new rhea::simplex_solver(); 
    }
    return self;
}

I switched all my variables to pointers and initialized with the new operator. I did that for variables, too. And it's working fine for now:

    self.centerPositionX = new rhea::variable(_centerPosition.x);
    self.centerPositionY = new rhea::variable(_centerPosition.y);

If you need to set a constraint I did it this way:

    _xConstraint = new rhea::constraint(*self.centerPositionX == _centerPosition.x);
    _yConstraint = new rhea::constraint(*self.centerPositionY == _centerPosition.y);

As your C++ code does use references and not pointers you will need to dereference the pointer with the indirection operator *pointer (more on that: https://www3.ntu.edu.sg/home/ehchua/programming/cpp/cp4_PointerReference.html). This is working fine for me, but I am not sure if this triggers a copy of the variable, which might be a problem later down the road or with other constructs of rhea I did not use so far.

Any clarification on that would be nice.

from rhea.

Nocte- avatar Nocte- commented on July 30, 2024

Is that idiomatic Obj-C++ though? You always have to do this if want to use any C++ object as a member?

Variables and constraints are reference counted, so a copy would still act like the original. The simplex_solver is a plain old, ordinary class.

from rhea.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.