Skip to content

Commit

Permalink
Add the CoreMIDI framework
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Jan 12, 2025
1 parent 3d888a0 commit 0fba880
Show file tree
Hide file tree
Showing 21 changed files with 308 additions and 76 deletions.
26 changes: 13 additions & 13 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/header-translator/src/availability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ impl Availability {
"swift" => {
_swift = Some(availability);
}
"driverkit" => {
"driverkit" | "bridgeos" => {
// Ignore
}
platform if platform.ends_with("_app_extension") => {
Expand Down
4 changes: 3 additions & 1 deletion crates/header-translator/src/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,11 +532,13 @@ impl ItemIdentifier<Option<String>> {
let mut id = Self::with_name(entity.get_name(), entity, context);

// union (unnamed at /Applications/Xcode.app/...)
// union (anonymous at /Applications/Xcode.app/...)
// enum (unnamed at /Applications/Xcode.app/...)
// struct (unnamed at /Applications/Xcode.app/...)
if id
.name
.as_deref()
.map(|name| name.contains(" (unnamed at"))
.map(|name| name.contains(" (unnamed at") || name.contains(" (anonymous at"))
.unwrap_or(false)
{
id.name = None;
Expand Down
42 changes: 25 additions & 17 deletions crates/header-translator/src/rust_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -626,30 +626,38 @@ impl Ty {
TypeKind::Double => Self::Primitive(Primitive::Double),
TypeKind::Record => {
let declaration = ty.get_declaration().expect("record declaration");
let id = ItemIdentifier::new_optional(&declaration, context);

let fields = ty
.get_fields()
.expect("struct fields")
.into_iter()
.map(|field| {
Self::parse(
field.get_type().expect("struct field type"),
Lifetime::Unspecified,
context,
)
})
.collect();
// Override for self-referential types
let fields = if matches!(
id.name.as_deref(),
Some(
"MIDISysexSendRequest" | "MIDISysexSendRequestUMP" | "MIDIDriverInterface"
)
) {
// Fake fields, we'll have to define it ourselves
vec![Self::Self_]
} else {
ty.get_fields()
.expect("struct fields")
.into_iter()
.map(|field| {
Self::parse(
field.get_type().expect("struct field type"),
Lifetime::Unspecified,
context,
)
})
.collect()
};

match declaration.get_kind() {
EntityKind::StructDecl => Self::Struct {
id: ItemIdentifier::new(&declaration, context),
id: id.map_name(|name| name.unwrap_or_else(|| "UnknownStruct".into())),
fields,
is_bridged: is_bridged(&declaration, context),
},
EntityKind::UnionDecl => Self::Union {
id: ItemIdentifier::new_optional(&declaration, context),
fields,
},
EntityKind::UnionDecl => Self::Union { id, fields },
_ => {
error!(?declaration, "unknown record type decl");
Self::GenericParam {
Expand Down
12 changes: 6 additions & 6 deletions crates/header-translator/src/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1198,7 +1198,7 @@ impl Stmt {
EntityKind::StructDecl | EntityKind::UnionDecl => {
let is_union = entity.get_kind() == EntityKind::UnionDecl;
let Some(id) = ItemIdentifier::new_optional(entity, context).to_option() else {
warn!(?entity, "skipped anonymous union");
warn!(?entity, "skipped anonymous union/struct");
return vec![];
};
let availability = Availability::parse(entity, context);
Expand Down Expand Up @@ -2377,18 +2377,18 @@ impl Stmt {
write!(f, "{}", self.cfg_gate_ln(config))?;
write!(f, "{availability}")?;
if *packed {
write!(f, "#[repr(C, packed)]")?;
writeln!(f, "#[repr(C, packed)]")?;
} else {
write!(f, "#[repr(C)]")?;
writeln!(f, "#[repr(C)]")?;
}
if *is_union || fields.iter().any(|(_, _, field)| field.contains_union()) {
write!(f, "#[derive(Clone, Copy)]")?;
writeln!(f, "#[derive(Clone, Copy)]")?;
} else {
// HACK to make Bool in structs work.
if fields.iter().any(|(_, _, field)| field.is_objc_bool()) {
write!(f, "#[derive(Clone, Copy, Debug)]")?;
writeln!(f, "#[derive(Clone, Copy, Debug)]")?;
} else {
write!(f, "#[derive(Clone, Copy, Debug, PartialEq)]")?;
writeln!(f, "#[derive(Clone, Copy, Debug, PartialEq)]")?;
}
}
if *is_union {
Expand Down
16 changes: 9 additions & 7 deletions crates/header-translator/src/unexposed_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,21 +249,23 @@ impl UnexposedAttr {
| "AVKIT_INIT_UNAVAILABLE"
| "CA_CANONICAL_DEPRECATED"
| "CB_CM_API_AVAILABLE"
| "CF_AUTOMATED_REFCOUNT_UNAVAILABLE"
| "CG_OBSOLETE"
| "deprecated"
| "DEPRECATED_ATTRIBUTE"
| "DISPATCH_UNAVAILABLE"
| "INTERAPP_AUDIO_DEPRECATED"
| "MIDICI1_0"
| "MIDICI1_1"
| "MIDICI1_2"
| "MIDI_API_UNAVAILABLE_NON_MACOS"
| "MIDI_AVAILABLE_UMP1_1"
| "MIDICI1_0_AVAILABILITY"
| "MIDICI1_1_AVAILABILITY"
| "MIDICI1_0_DEPRECATED"
| "MIDICI1_0"
| "MIDICI1_1_AVAILABILITY"
| "MIDICI1_1_DEPRECATED"
| "MIDI_AVAILABLE_UMP1_1"
| "MIDICI1_1"
| "MIDICI1_2"
| "MIDINETWORKSESSION_AVAILABLE"
| "MP_INIT_UNAVAILABLE"
| "CF_AUTOMATED_REFCOUNT_UNAVAILABLE"
| "CG_OBSOLETE"
| "NS_AUTOMATED_REFCOUNT_UNAVAILABLE"
| "NS_AUTOMATED_REFCOUNT_WEAK_UNAVAILABLE"
| "NS_UNAVAILABLE"
Expand Down
1 change: 1 addition & 0 deletions crates/objc2/src/topics/about_generated/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- `CoreGraphics` / `objc2-core-graphics`.
- `CoreFoundation` / `objc2-core-foundation`.
- `CoreMedia` / `objc2-core-media`.
- `CoreMIDI` / `objc2-core-midi`.
- `CoreText` / `objc2-core-text`.
- `CoreVideo` / `objc2-core-video`.
- `EventKitUI` / `objc2-event-kit-ui`.
Expand Down
1 change: 1 addition & 0 deletions crates/objc2/src/topics/about_generated/list_data.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
| `CoreGraphics` | [![`objc2-core-graphics`](https://badgen.net/crates/v/objc2-core-graphics)](https://crates.io/crates/objc2-core-graphics) | [![docs.rs](https://docs.rs/objc2-core-graphics/badge.svg)](https://docs.rs/objc2-core-graphics/) |
| `CoreImage` | [![`objc2-core-image`](https://badgen.net/crates/v/objc2-core-image)](https://crates.io/crates/objc2-core-image) | [![docs.rs](https://docs.rs/objc2-core-image/badge.svg)](https://docs.rs/objc2-core-image/) |
| `CoreLocation` | [![`objc2-core-location`](https://badgen.net/crates/v/objc2-core-location)](https://crates.io/crates/objc2-core-location) | [![docs.rs](https://docs.rs/objc2-core-location/badge.svg)](https://docs.rs/objc2-core-location/) |
| `CoreMIDI` | [![`objc2-core-midi`](https://badgen.net/crates/v/objc2-core-midi)](https://crates.io/crates/objc2-core-midi) | [![docs.rs](https://docs.rs/objc2-core-midi/badge.svg)](https://docs.rs/objc2-core-midi/) |
| `CoreML` | [![`objc2-core-ml`](https://badgen.net/crates/v/objc2-core-ml)](https://crates.io/crates/objc2-core-ml) | [![docs.rs](https://docs.rs/objc2-core-ml/badge.svg)](https://docs.rs/objc2-core-ml/) |
| `CoreMedia` | [![`objc2-core-media`](https://badgen.net/crates/v/objc2-core-media)](https://crates.io/crates/objc2-core-media) | [![docs.rs](https://docs.rs/objc2-core-media/badge.svg)](https://docs.rs/objc2-core-media/) |
| `CoreMotion` | [![`objc2-core-motion`](https://badgen.net/crates/v/objc2-core-motion)](https://crates.io/crates/objc2-core-motion) | [![docs.rs](https://docs.rs/objc2-core-motion/badge.svg)](https://docs.rs/objc2-core-motion/) |
Expand Down
3 changes: 3 additions & 0 deletions crates/test-frameworks/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ test-frameworks = [
"objc2-core-image/all",
"dep:objc2-core-location",
"objc2-core-location/all",
"dep:objc2-core-midi",
"objc2-core-midi/all",
"dep:objc2-core-ml",
"objc2-core-ml/all",
"dep:objc2-core-media",
Expand Down Expand Up @@ -212,6 +214,7 @@ objc2-core-data = { path = "../../framework-crates/objc2-core-data", optional =
objc2-core-foundation = { path = "../../framework-crates/objc2-core-foundation", optional = true }
objc2-core-graphics = { path = "../../framework-crates/objc2-core-graphics", optional = true }
objc2-core-location = { path = "../../framework-crates/objc2-core-location", optional = true }
objc2-core-midi = { path = "../../framework-crates/objc2-core-midi", optional = true }
objc2-core-ml = { path = "../../framework-crates/objc2-core-ml", optional = true }
objc2-core-media = { path = "../../framework-crates/objc2-core-media", optional = true }
objc2-core-text = { path = "../../framework-crates/objc2-core-text", optional = true }
Expand Down
15 changes: 11 additions & 4 deletions framework-crates/objc2-audio-toolbox/Cargo.toml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 0 additions & 19 deletions framework-crates/objc2-audio-toolbox/translation-config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,25 +75,6 @@ fn.GetNameFromSoundBank.skipped = true
fn.MusicSequenceLoadSMFWithFlags.skipped = true
fn.MusicSequenceSaveMIDIFile.skipped = true

# Needs CoreMIDI
fn.CAClockParseMIDI.skipped = true
typedef.AUMIDIOutputCallback.skipped = true
struct.AUMIDIOutputCallbackStruct.skipped = true
typedef.AUMIDIOutputCallbackStruct.skipped = true
class.AUAudioUnit.methods."profileStateForCable:channel:".skipped = true
class.AUAudioUnit.methods."enableProfile:cable:onChannel:error:".skipped = true
class.AUAudioUnit.methods."disableProfile:cable:onChannel:error:".skipped = true
typedef.AUMIDICIProfileChangedBlock.skipped = true
class.AUAudioUnit.methods.profileChangedBlock.skipped = true
class.AUAudioUnit.methods."setProfileChangedBlock:".skipped = true
class.AUAudioUnit.methods.AudioUnitMIDIProtocol.skipped = true
class.AUAudioUnit.methods.hostMIDIProtocol.skipped = true
class.AUAudioUnit.methods."setHostMIDIProtocol:".skipped = true
fn.MusicSequenceSetMIDIEndpoint.skipped = true
fn.MusicTrackSetDestMIDIEndpoint.skipped = true
fn.MusicTrackGetDestMIDIEndpoint.skipped = true
fn.MusicDeviceMIDIEventList.skipped = true

# Needs dispatch_queue_t from libdispatch
fn.AudioQueueNewOutputWithDispatchQueue.skipped = true
fn.AudioQueueNewInputWithDispatchQueue.skipped = true
Expand Down
9 changes: 7 additions & 2 deletions framework-crates/objc2-avf-audio/Cargo.toml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 0 additions & 5 deletions framework-crates/objc2-avf-audio/translation-config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@ visionos = "1.0"
class.AVAudioEngine.methods."connectMIDI:to:format:eventListBlock:".skipped = true
class.AVAudioEngine.methods."connectMIDI:toNodes:format:eventListBlock:".skipped = true

# Needs MIDIEndpointRef and MIDIEventList from CoreMIDI
class.AVMusicTrack.methods.destinationMIDIEndpoint.skipped = true
class.AVMusicTrack.methods."setDestinationMIDIEndpoint:".skipped = true
class.AVAudioUnitMIDIInstrument.methods."sendMIDIEventList:".skipped = true

# Both the NSObject superclass and the AVAudioSessionDeprecated category defines this
class.AVAudioSession.methods.init.skipped = true
class.AVAudioSession.methods.new.skipped = true # Use sharedInstance
Expand Down
Loading

0 comments on commit 0fba880

Please sign in to comment.