J.Doe
J.Doe

Reputation: 1552

Creating a cross platform c++ touch manager. Passing Objective-c objects in c++ involved code

So I am trying to create a multitouch class that can be used cross platform (iOS, Android, etc). The goal is that the engine does not need to know the platform in order to get updated touch data.

Right now I am doing the general design and am specifically implementing the iOS side. The Android etc side will come much later.

In order to do this I am trying to use the delegation pattern. There are really only two interface items.

There is a method update(float dt) to be called on each new frame with the dt. This method then will return a c++ struct of information about all the touches or perhaps set a property that can be accessed. I am not sure.

On the iOS side the only other function that needs to be called from outside is touchesDown which passes in a NSSet* of the UITouches and the UIView that they are in.

Here is the design I am working with thus far

Multitouch\
    PlatformTouchManager.h (C++ Abstract Class with Update)
    iOS\
        iOSMultiTouch.cpp (Objective-c++)
        iOSMultiTouch.hpp (Objective-c++ Class inheriting PlatformTouchManager)
    MultTouch.cpp (C++)
    MultiTouch.h (C++ class)

Here is PlatformTouchManager.h

#define MAX_TOUCHES 5
#define PLATFORM_iOS
//#define PLATFORM_ANDROID

class PlatformTouchManager {
public:
    // Update All The Events
    virtual void update(float time) = 0;
};

And of course Multitouch.h

class Multitouch {
private:
    PlatformTouchManager* manager;
public:
    Multitouch() {
#ifdef PLATFORM_iOS
        manager = new iOSMultiTouch();
#endif
    }
    ~Multitouch() {
        delete manager;
    }

    Multitouch(const Multitouch&) = delete;

    void update(float dt);

    void* getManager() {
        return manager;
    }
};

And finally iOSMultiTouch.hpp

#include <stdio.h>
#include "../PlatformTouchManager.h"
#include <set>
#import <UIKit/UIKit.h>

class iOSMultiTouch: public PlatformTouchManager {
public:
    // Initializer
    iOSMultiTouch();

    // Destructor
    ~iOSMultiTouch();

    // Update All The Events
    void update(float time);

    // Touch Down Set
    void touchesDown(id<NSSet> set, id<UIView> view);
};

It may be worth noting that this code is included by MultiTouch.h (c++) and my native view code which is objective-c++.

The cross platform engine thus creates a Multitouch object, keeps a reference and every frame calls update.

I am imagining that then iOS UIView will get the Multitouch* from the cross platform engine. Cast it into a iOSMultiTouch* object and call touchesDown:(NSSet *)touches withEvent:(IUView *)view on the delegate.

I am having a serious problem doing this.

If I try to import UIKit inside iOSMUltiTouch.hpp it causes build chaos so it would appear I can only import it inside of the source file. Therefore my touch down method needs to be void touchesDown(void* touches, void* view);.

The problem is then implementing this as when I try to cast these void* pointers into their proper types I get the warning Cast of C pointer type void* to objective-c pointer type id requires a bridged cast.

I understand that there are some ARC concerns here as ARC cannot track such things when casted into a primitive pointer but how do I get around this?

iOSTouchManager does indeed need to hold a strong reference to the UITouch objects up until after the frame the touch is released.

How do I implement this cast? Is there a different way I should be designing my classes to make this easier?

For those of you who were wondering these are the errors that pop up should you import uikit from iOSMultiTouch.hpp

Parse Issue

Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:512:1: Expected unqualified-id
../Multitouch/MultiTouch.cpp:9:10: In file included from ../Multitouch/MultiTouch.cpp:9:
../Multitouch/MultiTouch.h:15:10: In file included from ../Multitouch/MultiTouch.h:15:
../Multitouch/iOS/iOSMultiTouch.hpp:15:9: In file included from ../Multitouch/iOS/iOSMultiTouch.hpp:15:
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:8:9: In file included from Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:8:
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:8:9: In file included from Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:8:

Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSZone.h:9:1: Expected unqualified-id
../Multitouch/MultiTouch.cpp:9:10: In file included from ../Multitouch/MultiTouch.cpp:9:
../Multitouch/MultiTouch.h:15:10: In file included from ../Multitouch/MultiTouch.h:15:
../Multitouch/iOS/iOSMultiTouch.hpp:15:9: In file included from ../Multitouch/iOS/iOSMultiTouch.hpp:15:
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:8:9: In file included from Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:8:
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:10:9: In file included from Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:10:
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSArray.h:5:9: In file included from Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSArray.h:5:
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObject.h:8:9: In file included from Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObject.h:8:

Semantic Issues

Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:514:9: Unknown type name 'NSString'
../Multitouch/MultiTouch.cpp:9:10: In file included from ../Multitouch/MultiTouch.cpp:9:
../Multitouch/MultiTouch.h:15:10: In file included from ../Multitouch/MultiTouch.h:15:
../Multitouch/iOS/iOSMultiTouch.hpp:15:9: In file included from ../Multitouch/iOS/iOSMultiTouch.hpp:15:
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:8:9: In file included from Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:8:
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:8:9: In file included from Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:8:

Upvotes: 2

Views: 361

Answers (1)

trungduc
trungduc

Reputation: 12154

Problem

You got ton of errors because you imported iOS framework (UIKit) inside a C++ file (iOSMultiTouch.cpp).

Solution

For implementation files which you need to import iOS frameworks to, you have to use .mm instead of .cpp extension. .cpp is C++ extension, not Objective-C++ extension.

In this case, you need to rename iOSMultiTouch.cpp to iOSMultiTouch.mm. Replace void * with Objective-C pointers and it will work as expected.


Utils.h will keep nothing related to Objective-C and can be used anywhere. Utils.mm is used to work with Objective-C parts.

Utils.h

PlatformTouchManager* GetIOSTouchManager();

Utils.mm

#include "Utils.h"
#include "iOSMultiTouch.hpp"

PlatformTouchManager* GetIOSTouchManager() {
  return new iOSMultiTouch();
};

Multitouch.h

#include "Utils.h"
// Other include

class Multitouch {
  private:
  PlatformTouchManager* manager;
  public:
  Multitouch() {
#ifdef PLATFORM_iOS
    manager = GetIOSTouchManager();
#endif
  }
  ~Multitouch() {
    delete manager;
  }

  Multitouch(const Multitouch&) = delete;

  void update(float dt);

  PlatformTouchManager* getManager() {
    return manager;
  }
};

Upvotes: 2

Related Questions