Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Source/Experimental/CommandQueue/RiveCommandQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,15 @@ NS_SWIFT_NAME(CommandQueueProtocol)
path:(NSString*)path
requestID:(uint64_t)requestID;

/**
* Requests the name of a view model instance.
*
* @param viewModelInstanceHandle The handle of the view model instance
* @param requestID The request ID for correlating the response
*/
- (void)requestViewModelInstanceName:(uint64_t)viewModelInstanceHandle
requestID:(uint64_t)requestID;

/**
* Sets the string value of a view model property.
*
Expand Down
30 changes: 30 additions & 0 deletions Source/Experimental/CommandQueue/RiveCommandQueue.mm
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,11 @@ virtual void onViewModelListSizeReceived(
std::string path,
size_t size) override;

virtual void onViewModelInstanceNameReceived(
const rive::ViewModelInstanceHandle handle,
uint64_t requestId,
std::string name) override;

private:
__weak id<RiveViewModelInstanceListener> _observer;
};
Expand Down Expand Up @@ -730,6 +735,21 @@ virtual void onViewModelListSizeReceived(
}
}

void _ViewModelInstanceListener::onViewModelInstanceNameReceived(
const rive::ViewModelInstanceHandle handle,
uint64_t requestId,
std::string name)
{
if (_observer)
{
NSString* nsName = [NSString stringWithUTF8String:name.c_str()];
[_observer
onViewModelInstanceNameReceived:reinterpret_cast<uint64_t>(handle)
requestID:requestId
name:nsName];
}
}

namespace
{
class _RenderImageListener : public rive::CommandQueue::RenderImageListener
Expand Down Expand Up @@ -1748,6 +1768,16 @@ - (void)requestViewModelInstanceListSize:(uint64_t)viewModelInstanceHandle
}];
}

- (void)requestViewModelInstanceName:(uint64_t)viewModelInstanceHandle
requestID:(uint64_t)requestID
{
[self executeCommand:^{
auto handle = reinterpret_cast<rive::ViewModelInstanceHandle>(
viewModelInstanceHandle);
self->_commandQueue->requestViewModelInstanceName(handle, requestID);
}];
}

- (void)setViewModelInstanceString:(uint64_t)viewModelInstanceHandle
path:(NSString*)path
value:(NSString*)value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ NS_SWIFT_NAME(ViewModelInstanceListener)
path:(NSString*)path
size:(NSInteger)size;

- (void)onViewModelInstanceNameReceived:(uint64_t)viewModelInstanceHandle
requestID:(uint64_t)requestID
name:(NSString*)name;

@end

NS_ASSUME_NONNULL_END
Expand Down
18 changes: 17 additions & 1 deletion Source/Experimental/DataBinding/ViewModelInstance.swift
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,24 @@ public class ViewModelInstance: Equatable {
return lhs.viewModelInstanceHandle == rhs.viewModelInstanceHandle
}

// MARK: - Name

/// Retrieves the name of this view model instance.
///
/// The name is resolved from the C++ runtime via the command queue.
/// For named instances (created via `.name("myInstance", from:)`), this returns
/// the instance name as defined in the Rive file. For default or blank instances,
/// the name comes from the Rive file's default instance naming.
///
/// - Returns: The name of this view model instance
/// - Throws: An error if the name cannot be retrieved
@MainActor
public func name() async throws -> String {
return try await dependencies.viewModelInstanceService.name(for: viewModelInstanceHandle)
}

// MARK: - StringProperty

/// Retrieves the current value of a string property.
///
/// - Parameter property: The string property to read
Expand Down
34 changes: 34 additions & 0 deletions Source/Experimental/DataBinding/ViewModelInstanceService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,24 @@ class ViewModelInstanceService: NSObject, ViewModelInstanceListener {
self.dependencies = dependencies
}

// MARK: - Name

/// Retrieves the name of a view model instance.
///
/// The continuation is resumed when `onViewModelInstanceNameReceived` is called.
///
/// - Parameter instance: The view model instance handle
/// - Returns: The name of the view model instance
@MainActor
func name(for instance: ViewModelInstance.ViewModelInstanceHandle) async throws -> String {
let commandQueue = dependencies.commandQueue
return try await withCheckedThrowingContinuation { continuation in
let requestID = commandQueue.nextRequestID
continuations[requestID] = AnyContinuation(continuation)
commandQueue.requestViewModelInstanceName(instance, requestID: requestID)
}
}

/// Creates a blank view model instance from an artboard.
///
/// Delegates to the command queue. Returns immediately with the instance handle.
Expand Down Expand Up @@ -694,6 +712,22 @@ class ViewModelInstanceService: NSObject, ViewModelInstanceListener {
}
}

/// Called when a view model instance name is received.
///
/// Listener callback invoked by the command server. Dispatches to main actor to access
/// continuations dictionary and resume the continuation with the instance name.
nonisolated public func onViewModelInstanceNameReceived(
_ viewModelInstanceHandle: UInt64,
requestID: UInt64,
name: String
) {
Task { @MainActor in
if let continuation = continuations.removeValue(forKey: requestID) {
try continuation.resume(with: .success(name))
}
}
}

/// Called when view model list size is received.
///
/// Listener callback invoked by the command server. Dispatches to main actor to access
Expand Down