Class: AEM::Application

Inherits:
AEMReference::Query show all
Defined in:
lib/aem.rb

Overview

Application class

Constant Summary collapse

Event =

Application subclasses can override this class constant (usually with a subclass of Send::Event) to modify how Apple events are created and/or sent.

Send::Event
@@_app_number_count =

Workaround for lack of proper destructors in Ruby; see #initialize method.

0
@@_transaction_ids_by_app_no =
{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, address_desc, identity) ⇒ Application

Returns a new instance of Application.



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/aem.rb', line 85

def initialize(path, address_desc, identity)
  # called by constructor method
  # path is used by #reconnect
  # address_desc is an AEAddressDesc identifying the target application
  # identity is used by #inspect, #hash, #==
  @_transaction = KAE::KAnyTransactionID
  @_path = path
  @address_desc = address_desc
  @identity = identity
  @hash = identity.hash
  # workaround for lack of proper destructors; if a transaction is still open when Application instance is garbage collected, the following finalizer will automatically close it. Note: object IDs were different for some reason, so class maintains its own unique ids.
  @app_number = app_number = (@@_app_number_count += 1)
  @@_transaction_ids_by_app_no[app_number] = @_transaction
  ObjectSpace.define_finalizer(WeakRef.new(self), proc do
                                 transaction_id = @@_transaction_ids_by_app_no.delete(app_number)
                                 if transaction_id != KAE::KAnyTransactionID
                                   self.class::Event.new(@address_desc, 'miscendt', {}, {}, transaction_id).send(60, KAE::KAENoReply)
                                 end
                               end)
end

Instance Attribute Details

#address_descObject (readonly)

Returns the value of attribute address_desc.



71
72
73
# File 'lib/aem.rb', line 71

def address_desc
  @address_desc
end

#hashObject (readonly)

Returns the value of attribute hash.



71
72
73
# File 'lib/aem.rb', line 71

def hash
  @hash
end

#identityObject (readonly)

Returns the value of attribute identity.



71
72
73
# File 'lib/aem.rb', line 71

def identity
  @identity
end

Class Method Details

.by_desc(desc) ⇒ Object



159
160
161
162
# File 'lib/aem.rb', line 159

def Application.by_desc(desc)
  # desc : AEDesc -- an AEAddressDesc
  return new(nil, desc, [:desc, desc.type, desc.data])
end

.by_path(path) ⇒ Object

constructors



142
143
144
145
146
147
# File 'lib/aem.rb', line 142

def Application.by_path(path)
  # path : string  -- full path to local application
  #
  # Note: application will be launched if not already running.
  return new(path, Connect.local_app(path), [:path, path])
end

.by_pid(pid) ⇒ Object



154
155
156
157
# File 'lib/aem.rb', line 154

def Application.by_pid(pid)
  # pid : integer -- Unix process id
  return new(nil, Connect.local_app_by_pid(pid), [:pid, pid])
end

.by_url(url) ⇒ Object



149
150
151
152
# File 'lib/aem.rb', line 149

def Application.by_url(url)
  # url : string -- eppc URL for remote process
  return new(nil, Connect.remote_app(url), [:url, url])
end

.currentObject



164
165
166
# File 'lib/aem.rb', line 164

def Application.current
  return new(nil, Connect::CurrentApp, [:current])
end

.launch(path) ⇒ Object

utility class methods; placed here for convenience



109
110
111
112
# File 'lib/aem.rb', line 109

def Application.launch(path)
  # Launches a local application without sending it the usual 'run' event (aevtoapp).
  Connect.launch_app_with_launch_event(path)
end

.process_exists_for_desc?(desc) ⇒ Boolean

Returns:

  • (Boolean)


132
133
134
135
136
137
# File 'lib/aem.rb', line 132

def Application.process_exists_for_desc?(desc)
  # Does an application process specified by the given AEAddressDesc exist?
  # Returns false if process doesn't exist or if access to it isn't allowed.
  # (Implementation note: this method sends an Apple event to the specified process and checks for errors.)
  return Connect.process_exists_for_desc?(desc)
end

.process_exists_for_path?(path) ⇒ Boolean

Returns:

  • (Boolean)


114
115
116
117
118
# File 'lib/aem.rb', line 114

def Application.process_exists_for_path?(path)
  # Does a local process launched from the specified application file exist?
  # Note: if path is invalid, an AE::MacOSError is raised.
  return Connect.process_exists_for_path?(path)
end

.process_exists_for_pid?(pid) ⇒ Boolean

Returns:

  • (Boolean)


120
121
122
123
# File 'lib/aem.rb', line 120

def Application.process_exists_for_pid?(pid)
  # Is there a local application process with the given unix process id?
  return Connect.process_exists_for_pid?(pid)
end

.process_exists_for_url?(url) ⇒ Boolean

Returns:

  • (Boolean)


125
126
127
128
129
130
# File 'lib/aem.rb', line 125

def Application.process_exists_for_url?(url)
  # Does an application process specified by the given eppc:// URL exist?
  # Returns false if process doesn't exist or if access to it isn't allowed.
  # (Implementation note: this method sends an Apple event to the specified process and checks for errors.)
  return Connect.process_exists_for_url?(url)
end

Instance Method Details

#==(val) ⇒ Object Also known as: eql?



182
183
184
# File 'lib/aem.rb', line 182

def ==(val)
  return (self.class == val.class and @identity == val.identity)
end

#abort_transactionObject



231
232
233
234
235
236
237
238
239
240
# File 'lib/aem.rb', line 231

def abort_transaction
  # Abort the current transaction.
  if @_transaction == KAE::KAnyTransactionID
    raise RuntimeError, "No transaction is active."
  end
  self.class::Event.new(@address_desc, 'miscttrm', {}, {}, @_transaction).send
  @_transaction = KAE::KAnyTransactionID
  @@_transaction_ids_by_app_no[@app_number] = KAE::KAnyTransactionID
  return
end

#AEM_comparableObject

(hash method is provided by attr_reader :hash)



190
191
192
# File 'lib/aem.rb', line 190

def AEM_comparable
  return ['AEMApplication', @identity]
end

#AEM_pack_self(codecs) ⇒ Object



194
195
196
# File 'lib/aem.rb', line 194

def AEM_pack_self(codecs)
  return @address_desc
end

#begin_transaction(session = nil) ⇒ Object



221
222
223
224
225
226
227
228
229
# File 'lib/aem.rb', line 221

def begin_transaction(session=nil)
  # Begin a new transaction.
  if @_transaction != KAE::KAnyTransactionID
    raise RuntimeError, "Transaction is already active."
  end
  @_transaction = self.class::Event.new(@address_desc, 'miscbegi', session != nil ? {'----' => session} : {}).send
  @@_transaction_ids_by_app_no[@app_number] = @_transaction
  return
end

#end_transactionObject



242
243
244
245
246
247
248
249
250
251
# File 'lib/aem.rb', line 242

def end_transaction
  # End the current transaction.
  if @_transaction == KAE::KAnyTransactionID
    raise RuntimeError, "No transaction is active."
  end
  self.class::Event.new(@address_desc, 'miscendt', {}, {}, @_transaction).send
  @_transaction = KAE::KAnyTransactionID
  @@_transaction_ids_by_app_no[@app_number] = KAE::KAnyTransactionID
  return
end

#event(event, params = {}, atts = {}, return_id = KAE::KAutoGenerateReturnID, codecs = DefaultCodecs) ⇒ Object



211
212
213
214
215
216
217
218
219
# File 'lib/aem.rb', line 211

def event(event, params={}, atts={}, return_id=KAE::KAutoGenerateReturnID, codecs=DefaultCodecs)
  # Construct an Apple event targetted at this application.
  # event  : string -- 8-letter code indicating event's class, e.g. 'coregetd'
  # params : hash -- a dict of form {AE_code:anything,...} containing zero or more event parameters (message arguments)
  # atts : hash -- a dict of form {AE_code:anything,...} containing zero or more event attributes (event info)
  # return_id : integer  -- reply event's ID
  # codecs : Codecs -- codecs object to use when packing/unpacking this event
  return self.class::Event.new(@address_desc, event, params, atts, @_transaction, return_id, codecs)
end

#inspectObject Also known as: to_s

methods



171
172
173
174
175
176
177
178
# File 'lib/aem.rb', line 171

def inspect
  if @identity[0] == :current
    return "#{self.class}.current"
  else
    con_name = {:path => 'by_path', :url => 'by_url', :pid => 'by_pid', :desc => 'by_desc'}[@identity[0]]
    return "#{self.class}.#{con_name}(#{@identity[1].inspect})"
  end
end

#reconnectObject



198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/aem.rb', line 198

def reconnect
  # If application has quit since this Application object was created, its AEAddressDesc
  # is no longer valid so this Application object will not work even when application is restarted.
  # #reconnect will update this Application object's AEAddressDesc so it's valid again.
  #
  # Note that this only works for Application objects created via the by_path constructor.
  # Also note that any Event objects created prior to calling #reconnect will still be invalid.
  if @_path
    @address_desc = Connect.local_app(@_path)
  end
  return
end