Update macos build
This commit is contained in:
19
openVulkanoCpp/Host/Apple/BundledResoureLoaderIos.h
Normal file
19
openVulkanoCpp/Host/Apple/BundledResoureLoaderIos.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#include "Host/ResourceLoader.hpp"
|
||||
|
||||
namespace OpenVulkano
|
||||
{
|
||||
class BundledResourceLoaderIOS : public ResourceLoader
|
||||
{
|
||||
public:
|
||||
Array<char> GetResource(const std::string& resourceName) override;
|
||||
};
|
||||
}
|
||||
30
openVulkanoCpp/Host/Apple/BundledResoureLoaderIos.mm
Normal file
30
openVulkanoCpp/Host/Apple/BundledResoureLoaderIos.mm
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "BundledResoureLoaderIos.h"
|
||||
#include "Base/Logger.hpp"
|
||||
#include "Base/Utils.hpp"
|
||||
|
||||
namespace OpenVulkano
|
||||
{
|
||||
namespace
|
||||
{
|
||||
void* LOADER_HANDLE = ResourceLoader::RegisterResourceLoader(std::move(std::unique_ptr<ResourceLoader>(new BundledResourceLoaderIOS())));
|
||||
}
|
||||
|
||||
|
||||
Array<char> BundledResourceLoaderIOS::GetResource(const std::string& resourceName)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
auto [fileName, fileType] = Utils::SplitAtLastOccurrence(resourceName, '.');
|
||||
NSString* filePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithUTF8String:fileName.c_str()] ofType:[NSString stringWithUTF8String:fileType.c_str()]];
|
||||
return Utils::ReadFile(std::string([filePath UTF8String]));
|
||||
}
|
||||
Logger::FILESYS->warn("Failed to find resource: '{}' in bundle", resourceName);
|
||||
return {0};
|
||||
}
|
||||
}
|
||||
98
openVulkanoCpp/Host/Apple/MetalViewWindow.h
Normal file
98
openVulkanoCpp/Host/Apple/MetalViewWindow.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Base/UI/IVulkanWindow.hpp"
|
||||
|
||||
namespace OpenVulkano
|
||||
{
|
||||
class MetalViewWindow final : public IVulkanWindow
|
||||
{
|
||||
WindowConfiguration windowConf;
|
||||
IWindowHandler* handler = nullptr;
|
||||
void* caMetalLayer = nullptr;
|
||||
bool tickHandler = true;
|
||||
float contentScale = 1;
|
||||
float orientation = 0;
|
||||
|
||||
public:
|
||||
void Init(RenderAPI::RenderApi renderApi) override {}
|
||||
|
||||
void Init(void* metalLayer, Math::Vector2ui size)
|
||||
{
|
||||
caMetalLayer = metalLayer;
|
||||
windowConf.size = size;
|
||||
}
|
||||
|
||||
void SetMetalLayer(void* metalLayer) { caMetalLayer = metalLayer; }
|
||||
|
||||
bool HasTitle() override { return false; }
|
||||
|
||||
const std::string& GetTitle() override { return windowConf.title; }
|
||||
|
||||
void SetTitle(const std::string& title) override {}
|
||||
|
||||
WindowMode GetWindowMode() override { return FULLSCREEN; }
|
||||
|
||||
void SetWindowMode(WindowMode) override {}
|
||||
|
||||
const WindowConfiguration& GetWindowConfiguration() override { return windowConf; }
|
||||
|
||||
void SetSize(uint32_t width, uint32_t height) override { windowConf.size = { width, height }; }
|
||||
|
||||
void SetSizeLimits(int minWidth, int minHeight, int maxWidth, int maxHeight) override {}
|
||||
|
||||
Math::Vector2i GetPosition() override { return { 0, 0 }; }
|
||||
|
||||
void SetPosition(int posX, int posY) override {}
|
||||
|
||||
void Show() override {}
|
||||
|
||||
void Hide() override {}
|
||||
|
||||
void Show(bool show) override {}
|
||||
|
||||
IWindowHandler* GetWindowHandler() override { return handler; }
|
||||
|
||||
void SetWindowHandler(IWindowHandler* handler) override { this->handler = handler; }
|
||||
|
||||
uint32_t GetWindowId() const override { return 0; }
|
||||
|
||||
IOpenGlWindow* GetOpenGlWindow() override { return nullptr; }
|
||||
|
||||
IVulkanWindow* GetVulkanWindow() override { return this; }
|
||||
|
||||
bool WindowHasBeenDestroyed() const override { return false; }
|
||||
|
||||
void SetWindowHasBeenDestroyed() override
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
void* GetNativeWindowHandle() override { return caMetalLayer; }
|
||||
|
||||
vk::SurfaceKHR CreateSurface(const vk::Instance& instance, const vk::AllocationCallbacks* pAllocator = nullptr) override;
|
||||
|
||||
std::vector<std::string> GetRequiredInstanceExtensions() override;
|
||||
|
||||
Math::Vector2ui GetSize() override { return windowConf.size; }
|
||||
|
||||
void Close() override {}
|
||||
|
||||
void OnResize(uint32_t width, uint32_t height);
|
||||
|
||||
virtual float GetContentScale() const override { return contentScale; }
|
||||
|
||||
virtual float GetInterfaceOrientation() const override { return orientation; }
|
||||
|
||||
void SetContentScale(float scale) { contentScale = scale; }
|
||||
|
||||
void SetOrientation(float orientation) { this->orientation = orientation; }
|
||||
|
||||
void TickHandler();
|
||||
};
|
||||
}
|
||||
53
openVulkanoCpp/Host/Apple/MetalViewWindow.mm
Normal file
53
openVulkanoCpp/Host/Apple/MetalViewWindow.mm
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
// Makre usre the Molten include is first!
|
||||
#include <MoltenVK/mvk_vulkan.h>
|
||||
|
||||
#include "MetalViewWindow.h"
|
||||
#include "Base/Logger.hpp"
|
||||
#include "Host/GraphicsAppManager.hpp"
|
||||
|
||||
#import <MetalKit/MTKView.h>
|
||||
|
||||
namespace OpenVulkano
|
||||
{
|
||||
vk::SurfaceKHR MetalViewWindow::CreateSurface(const vk::Instance& instance, const vk::AllocationCallbacks* pAllocator)
|
||||
{
|
||||
VkMetalSurfaceCreateInfoEXT surfaceCreateInfo;
|
||||
surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
|
||||
surfaceCreateInfo.pNext = NULL;
|
||||
surfaceCreateInfo.flags = 0;
|
||||
surfaceCreateInfo.pLayer = (CAMetalLayer*) caMetalLayer;
|
||||
|
||||
VkSurfaceKHR surface;
|
||||
auto err = vkCreateMetalSurfaceEXT(static_cast<VkInstance>(instance), &surfaceCreateInfo, NULL, &surface);
|
||||
return {surface};
|
||||
}
|
||||
|
||||
std::vector<std::string> MetalViewWindow::GetRequiredInstanceExtensions()
|
||||
{
|
||||
return {}; //TODO
|
||||
}
|
||||
|
||||
void MetalViewWindow::OnResize(uint32_t newWidth, uint32_t newHeight)
|
||||
{
|
||||
Logger::WINDOW->debug("Window (id: {0}) resized (width: {1}, height: {2})", GetWindowId(), newWidth, newHeight);
|
||||
if (handler)
|
||||
handler->OnWindowResize(this, newWidth, newHeight);
|
||||
}
|
||||
|
||||
void MetalViewWindow::TickHandler()
|
||||
{
|
||||
if (tickHandler)
|
||||
{
|
||||
if (auto graphApp = dynamic_cast<GraphicsAppManager*>(handler))
|
||||
{
|
||||
graphApp->LoopTick();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
openVulkanoCpp/Host/Apple/NamedEventProcessor.h
Normal file
30
openVulkanoCpp/Host/Apple/NamedEventProcessor.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Base/Event.hpp"
|
||||
|
||||
namespace OpenVulkano
|
||||
{
|
||||
class NamedEventProcessor final : public INamedEventProcessor
|
||||
{
|
||||
std::vector<std::string> m_classNamePrefixes, m_classNameSuffixes;
|
||||
bool m_useClassNameAsEventName;
|
||||
public:
|
||||
NamedEventProcessor(bool classNameAsEventName = false)
|
||||
: m_classNamePrefixes({ "", "Event" })
|
||||
, m_classNameSuffixes({ "Event", "" })
|
||||
, m_useClassNameAsEventName(classNameAsEventName)
|
||||
{}
|
||||
|
||||
void RegisterClassNamePrefix(const std::string& prefix) { m_classNamePrefixes.push_back(prefix); }
|
||||
|
||||
void RegisterClassNameSuffix(const std::string& suffix) { m_classNameSuffixes.push_back(suffix); }
|
||||
|
||||
void Notify(const std::string& eventName, const std::vector<Parameters>& parameters) const override;
|
||||
};
|
||||
}
|
||||
171
openVulkanoCpp/Host/Apple/NamedEventProcessor.mm
Normal file
171
openVulkanoCpp/Host/Apple/NamedEventProcessor.mm
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "NamedEventProcessor.h"
|
||||
#include "Base/Logger.hpp"
|
||||
#include <map>
|
||||
#include <typeindex>
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <objc/runtime.h>
|
||||
|
||||
namespace OpenVulkano
|
||||
{
|
||||
namespace
|
||||
{
|
||||
NamedEventProcessor appleNotificationNamedEventProcessor;
|
||||
|
||||
constexpr int LONGEST_TYPE_NAME = std::max({ sizeof(@encode(NSString*)), sizeof(@encode(BOOL)), sizeof(@encode(int)), sizeof(@encode(float)), sizeof(@encode(double)) });
|
||||
|
||||
std::map<std::type_index, std::string> TYPE_NAME_MAP = {
|
||||
{ std::type_index(typeid(std::string)), @encode(NSString*) },
|
||||
{ std::type_index(typeid(bool)), @encode(BOOL) },
|
||||
{ std::type_index(typeid(int)), @encode(int) },
|
||||
{ std::type_index(typeid(float)), @encode(float) },
|
||||
{ std::type_index(typeid(double)), @encode(double) },
|
||||
{ std::type_index(typeid(UUID)), @encode(NSUUID*) }
|
||||
};
|
||||
|
||||
// Keep this in sync with INamedEventProcessor! synctag: NamedEventProcessor_Parameters_SYNC_TAG
|
||||
union ParameterValue
|
||||
{
|
||||
NSString* string;
|
||||
BOOL boolean;
|
||||
int integer;
|
||||
float fp32;
|
||||
double fp64;
|
||||
NSUUID* uuid;
|
||||
};
|
||||
|
||||
std::string BuildTypeName(const std::vector<INamedEventProcessor::Parameters>& parameters)
|
||||
{
|
||||
std::string typeName("@:");
|
||||
typeName.reserve(2 + parameters.size() * (LONGEST_TYPE_NAME + 2));
|
||||
for(const auto& parameter : parameters)
|
||||
{
|
||||
typeName.append(std::visit([](auto&& arg) {
|
||||
return TYPE_NAME_MAP.find(typeid(std::decay_t<decltype(arg)>))->second;
|
||||
}, parameter));
|
||||
}
|
||||
return typeName;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ParameterValue CreateValue(const T& parameter)
|
||||
{
|
||||
ParameterValue value;
|
||||
reinterpret_cast<T&>(value) = parameter;
|
||||
return value;
|
||||
}
|
||||
|
||||
ParameterValue CreateValue(const std::string& parameter)
|
||||
{
|
||||
ParameterValue value;
|
||||
value.string = [NSString stringWithUTF8String:parameter.c_str()];
|
||||
return value;
|
||||
}
|
||||
|
||||
ParameterValue CreateValue(const UUID& parameter)
|
||||
{
|
||||
ParameterValue value;
|
||||
auto uuidData = parameter.binary();
|
||||
value.uuid = [[NSUUID alloc] initWithUUIDBytes:uuidData.data()];
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string SelectorType(Method m)
|
||||
{
|
||||
std::string sig;
|
||||
for (auto i = 0u, count = method_getNumberOfArguments(m); i < count; ++i)
|
||||
{
|
||||
auto argType = method_copyArgumentType(m, i);
|
||||
sig += std::string(argType);
|
||||
free(argType);
|
||||
}
|
||||
return sig;
|
||||
}
|
||||
|
||||
SEL GetInitForClass(Class c, const std::string &initType)
|
||||
{
|
||||
SEL init = nullptr;
|
||||
for (auto clazz = c; !init && clazz; clazz = class_getSuperclass(clazz))
|
||||
{
|
||||
if (Method *methods = class_copyMethodList(clazz, nullptr))
|
||||
{
|
||||
for (int i = 0; methods[i]; i++)
|
||||
{
|
||||
const std::string name = sel_getName(method_getName(methods[i]));
|
||||
const std::string type = SelectorType(methods[i]);
|
||||
if (0 == name.find("init") && type == initType)
|
||||
{
|
||||
init = method_getName(methods[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(methods);
|
||||
}
|
||||
}
|
||||
return init;
|
||||
}
|
||||
|
||||
Class FindGenericEventClass(const std::vector<std::string>& prefixes,
|
||||
const std::vector<std::string>& suffixes,
|
||||
const std::string& eventName)
|
||||
{ // Searching for class with all registered prefix/suffix combinations
|
||||
for (const std::string& suffix : suffixes)
|
||||
{
|
||||
for (const std::string& prefix: prefixes)
|
||||
{
|
||||
NSString* eventClassName = [NSString stringWithUTF8String:(prefix + eventName + suffix).c_str()];
|
||||
if (Class eventClass = NSClassFromString(eventClassName))
|
||||
{
|
||||
return eventClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void NamedEventProcessor::Notify(const std::string& eventName, const std::vector<Parameters>& parameters) const
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
if (Class eventClass = FindGenericEventClass(m_classNamePrefixes, m_classNameSuffixes, eventName))
|
||||
{
|
||||
if (SEL init = GetInitForClass(eventClass, BuildTypeName(parameters)))
|
||||
{
|
||||
NSObject* event = [eventClass alloc];
|
||||
auto inv = [NSInvocation invocationWithMethodSignature:[event methodSignatureForSelector:init]];
|
||||
[inv setTarget:event];
|
||||
[inv setSelector:init];
|
||||
for (int i = 0; i < parameters.size(); i++)
|
||||
{
|
||||
auto arg = std::visit([](auto&& arg) { return CreateValue(arg); }, parameters[i]);
|
||||
[inv setArgument:&arg atIndex:(i + 2)];
|
||||
}
|
||||
[inv invoke];
|
||||
for (Class clazz = eventClass; clazz && clazz != NSObject.class; clazz = class_getSuperclass(clazz))
|
||||
{
|
||||
NSString* notificationName;
|
||||
if (m_useClassNameAsEventName) notificationName = NSStringFromClass(clazz);
|
||||
else notificationName = [NSString stringWithUTF8String:eventName.c_str()];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:notificationName object:event userInfo:nil];
|
||||
}
|
||||
[event release];
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::MANAGER->error("Cannot find constructor for named event %s", eventName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::MANAGER->debug("Cannot find implementation for named event %s", eventName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user