C4Labs / C4iOS

C4 is an open-source creative coding framework that harnesses the power of native iOS programming with a simplified API that gets you working with media right away. Build artworks, design interfaces and explore new possibilities working with media and interaction.
www.c4ios.com
MIT License
980 stars 75 forks source link

'Object' is ambiguous for lookup in this context #180

Closed traviskirton closed 9 years ago

traviskirton commented 9 years ago

I've been working to convert Path so that is uses Rect instead of CGRect, which is a straightforward conversion. For example:

public func addCurveToPoint(control1: CGPoint, control2: CGPoint, point: CGPoint) {
    CGPathAddCurveToPoint(internalPath, nil, control1.x, control1.y, control2.x, control2.y, point.x, point.y) }

becomes...

public func addCurveToPoint(control1: Point, control2: Point, point: Point) {
    CGPathAddCurveToPoint(internalPath, nil, CGFloat(control1.x), CGFloat(control1.y), CGFloat(control2.x), CGFloat(control2.y), CGFloat(point.x), CGFloat(point.y))
}

I have made conversions like this throughout the file, and when I'm done there are no errors in Path.swift

However, once these changes are in place, I start to get a lot of errors with higher-level classes.

For example, in Polygon.swift:

func addPolygon(points: [CGPoint], closed: Bool = true) {

should be translated to:

func addPolygon(points: [Point], closed: Bool = true) {

ISSUE Changing to [Point] raises the following error:

Point is ambiguous for lookup in this context

This error happens all over the classes in C4iOS, with Point, Rect, etc... I have cleaned, deleted, rebuilt the Xcode project, and each of the frameworks multiple times... to no avail.

traviskirton commented 9 years ago

For reference, here is a copy of the Path.swift file:

import QuartzCore

/// Rules for determining the region of a path that gets filled with color.
public enum FillRule {
    /**
    Specifies the non-zero winding rule. Count each left-to-right path as +1 and each right-to-left path as -1. If the
    sum of all crossings is 0, the point is outside the path. If the sum is nonzero, the point is inside the path and
    the region containing it is filled.
    */
    case NonZero

    /**
    Specifies the even-odd winding rule. Count the total number of path crossings. If the number of crossings is even,
    the point is outside the path. If the number of crossings is odd, the point is inside the path and the region
    containing it should be filled.
    */
    case EvenOdd
}

/**
A Path is a sequence of geometric segments which can be straight lines or curves.
*/
@IBDesignable
public class Path: Equatable {
    internal var internalPath: CGMutablePathRef = CGPathCreateMutable()

    public init() {
        internalPath = CGPathCreateMutable()
    }

    internal init(path: CGMutablePathRef) {
        internalPath = path
    }

    /// Determine if the path is empty
    public func isEmpty() -> Bool {
        return CGPathIsEmpty(internalPath)
    }

    /**
    Return the path bounding box. The path bounding box is the smallest rectangle completely enclosing all points
    in the path, *not* including control points for Bézier cubic and quadratic curves. If the path is empty, then
    return `CGRectNull`.
    */
    public func boundingBox() -> Rect {
        return Rect(CGPathGetPathBoundingBox(internalPath))
    }

    /**
    Return true if `point` is contained in `path`; false otherwise. A point is contained in a path if it is inside the
    painted region when the path is filled; if `fillRule` is `EvenOdd`, then the even-odd fill rule is used to evaluate
    the painted region of the path, otherwise, the winding-number fill rule is used.
    */
    public func containsPoint(point: Point, fillRule: FillRule = .NonZero) -> Bool {
        return CGPathContainsPoint(internalPath, nil, CGPoint(point), fillRule == .EvenOdd)
    }

    /// Create a copy of the path
    public func copy() -> Path {
        return Path(path: CGPathCreateMutableCopy(internalPath))
    }
}

/// Determine if two paths are equal
public func == (left: Path, right: Path) -> Bool {
    return CGPathEqualToPath(left.internalPath, right.internalPath)
}

extension Path {
    /**
    Return the current point of the current subpath.
    */
    public var currentPoint: Point {
        get {
            return Point(CGPathGetCurrentPoint(internalPath))
        }
        set(point) {
            moveToPoint(point)
        }
    }

    /**
    Move the current point of the current subpath.
    */
    public func moveToPoint(point: Point) {
        CGPathMoveToPoint(internalPath, nil, CGFloat(point.x), CGFloat(point.y))
    }

    /**
    Append a straight-line segment fron the current point to `point` and move the current point to `point`.
    */
    public func addLineToPoint(point: Point) {
        CGPathAddLineToPoint(internalPath, nil, CGFloat(point.x), CGFloat(point.y))
    }

    /**
    Append a quadratic curve from the current point to `point` with control point `control` and move the current
    point to `point`.
    */
    public func addQuadCurveToPoint(#control: Point, point: Point) {
        CGPathAddQuadCurveToPoint(internalPath, nil, CGFloat(control.x), CGFloat(control.y), CGFloat(point.x), CGFloat(point.y))
    }

    /**
    Append a cubic Bézier curve from the current point to `point` with control points `control1` and `control2`
    and move the current point to `point`.
    */
    public func addCurveToPoint(control1: Point, control2: Point, point: Point) {
        CGPathAddCurveToPoint(internalPath, nil, CGFloat(control1.x), CGFloat(control1.y), CGFloat(control2.x), CGFloat(control2.y), CGFloat(point.x), CGFloat(point.y))
    }

    /**
    Append a line from the current point to the starting point of the current subpath and end the subpath.
    */
    public func closeSubpath() {
        CGPathCloseSubpath(internalPath)
    }

    /**
    Add a rectangle to the path.
    */
    public func addRect(rect: Rect) {
        CGPathAddRect(internalPath, nil, CGRect(rect))
    }

    /**
    Add a rounded rectangle to the path. The rounded rectangle coincides with the edges of `rect`. Each corner consists
    of one-quarter of an ellipse with axes equal to `cornerWidth` and `cornerHeight`. The rounded rectangle forms a
    complete subpath of the path --- that is, it begins with a "move to" and ends with a "close subpath" --- oriented
    in the clockwise direction.
    */
    public func addRoundedRect(rect: Rect, cornerWidth: Double, cornerHeight: Double) {
        CGPathAddRoundedRect(internalPath, nil, CGRect(rect), CGFloat(cornerWidth), CGFloat(cornerHeight))
    }

    /**
    Add an ellipse (an oval) inside `rect`. The ellipse is approximated by a sequence of Bézier curves. The center of
    the ellipse is the midpoint of `rect`. If `rect` is square, then the ellipse will be circular with radius equal to
    one-half the width (equivalently, one-half the height) of `rect`. If `rect` is rectangular, then the major- and
    minor-axes will be the width and height of `rect`. The ellipse forms a complete subpath --- that is, it begins with
    a "move to" and ends with a "close subpath" --- oriented in the clockwise direction. 
    */
    public func addEllipse(rect: Rect) {
        CGPathAddEllipseInRect(internalPath, nil, CGRect(rect))
    }

    /**
    Add an arc of a circle, possibly preceded by a straight line segment. The arc is approximated by a sequence of
    Bézier curves.

    :center:     The center of the arc.
    :radius:     The radius of the arc.
    :startAngle: The angle in radians to the first endpoint of the arc, measured counter-clockwise from the positive
                 x-axis.
    :delta:      The angle between `startAngle` and the second endpoint of the arc, in radians. If `delta' is positive,
                 then the arc is drawn counter-clockwise; if negative, clockwise.
    */
    public func addRelativeArc(center: Point, radius: Double, startAngle: Double, delta: Double) {
        CGPathAddRelativeArc(internalPath, nil, CGFloat(center.x), CGFloat(center.y), CGFloat(radius), CGFloat(startAngle), CGFloat(delta))
    }

    /**
    Add an arc of a circle, possibly preceded by a straight line segment. The arc is approximated by a sequence of
    Bézier curves.

    Note that using values very near 2π can be problematic. For example, setting `startAngle` to 0, `endAngle` to 2π,
    and `clockwise` to true will draw nothing. (It's easy to see this by considering, instead of 0 and 2π, the values
    ε and 2π - ε, where ε is very small.) Due to round-off error, however, it's possible that passing the value
    `2 * M_PI` to approximate 2π will numerically equal to 2π + δ, for some small δ; this will cause a full circle to
    be drawn.

    If you want a full circle to be drawn clockwise, you should set `startAngle` to 2π, `endAngle` to 0, and
    `clockwise` to true. This avoids the instability problems discussed above.

    :center:     The center of the arc.
    :radius:     The radius of the arc.
    :startAngle: The angle to the first endpoint of the arc in radians.
    :endAngle:   The angle to the second endpoint of the arc.
    :clockwise:  If true the arc is drawn clockwise.

    */
    public func addArc(center: Point, radius: Double, startAngle: Double, endAngle: Double, clockwise: Bool) {
        CGPathAddArc(internalPath, nil, CGFloat(center.x), CGFloat(center.y), CGFloat(radius), CGFloat(startAngle), CGFloat(endAngle), clockwise)
    }

    /**
    Add an arc of a circle, possibly preceded by a straight line segment. The arc is approximated by a sequence of
    Bézier curves. The resulting arc is tangent to the line from the current point to `point1`, and the line from
    `point1` to `point2`.
    */
    public func addArcToPoint(point1: Point, point2: Point, radius: Double) {
        CGPathAddArcToPoint(internalPath, nil, CGFloat(point1.x), CGFloat(point1.y), CGFloat(point2.x), CGFloat(point2.y), CGFloat(radius))
    }

    /**
    Append a path.
    */
    public func addPath(path: Path) {
        CGPathAddPath(internalPath, nil, path.internalPath)
    }

    public var CGPath: CGPathRef {
        get {
            return internalPath
        }
    }
}
traviskirton commented 9 years ago

Here's a cap of the error:

screen shot 2014-11-03 at 12 57 55 am

traviskirton commented 9 years ago

Wow. I looked around for a long time before writing this issue...

Answer:

C4Core.Point

All you have to do is specify the framework from which to look up the object type.

alejandro-isaza commented 9 years ago

Yeah, I guess there is another point object somewhere in the swift libraries. We could consider adding C4 prefix to every class.

traviskirton commented 9 years ago

Kept running into an issue with the Point class, Xcode was recognizing 2 different sources, so I added the C4 prefix to everything.