@leansdk/leanrc
Version:
LeanRC is a MVC framework for creating graceful applications
163 lines (136 loc) • 5.9 kB
text/coffeescript
# This file is part of LeanRC.
#
# LeanRC is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# LeanRC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with LeanRC. If not, see <https://www.gnu.org/licenses/>.
module.exports = (Module)->
{
PointerT
FuncG, DictG, UnionG, MaybeG, ListG
ViewInterface
ObserverInterface, NotificationInterface
MediatorInterface, ControllerInterface
CoreObject
} = Module::
class View extends CoreObject
@inheritProtected()
@implements ViewInterface
@module Module
@const MULTITON_MSG: "View instance for this multiton key already constructed!"
iphMediatorMap = PointerT @protected mediatorMap: DictG(String, MaybeG MediatorInterface)
iphObserverMap = PointerT @protected observerMap: DictG(String, MaybeG ListG ObserverInterface)
ipsMultitonKey = PointerT @protected multitonKey: MaybeG String
cphInstanceMap = PointerT @private @static _instanceMap: DictG(String, MaybeG ViewInterface),
default: {}
@public @static getInstance: FuncG(String, ViewInterface),
default: (asKey)->
unless View[cphInstanceMap][asKey]?
View[cphInstanceMap][asKey] = View.new asKey
View[cphInstanceMap][asKey]
@public @static removeView: FuncG(String),
default: (asKey)->
if (voView = View[cphInstanceMap][asKey])?
for asMediatorName in Reflect.ownKeys voView[iphMediatorMap]
voView.removeMediator asMediatorName
View[cphInstanceMap][asKey] = undefined
delete View[cphInstanceMap][asKey]
return
@public registerObserver: FuncG([String, ObserverInterface]),
default: (asNotificationName, aoObserver)->
vlObservers = @[iphObserverMap][asNotificationName]
if vlObservers?
vlObservers.push aoObserver
else
@[iphObserverMap][asNotificationName] = [aoObserver]
return
@public removeObserver: FuncG([String, UnionG ControllerInterface, MediatorInterface]),
default: (asNotificationName, aoNotifyContext)->
vlObservers = @[iphObserverMap][asNotificationName] ? []
for voObserver, i in vlObservers
break if do (voObserver)->
if voObserver.compareNotifyContext aoNotifyContext
vlObservers[i..i] = []
return yes
return no
if vlObservers.length is 0
delete @[iphObserverMap][asNotificationName]
return
@public notifyObservers: FuncG(NotificationInterface),
default: (aoNotification)->
vsNotificationName = aoNotification.getName()
vlObservers = @[iphObserverMap][vsNotificationName]
if vlObservers?
vlNewObservers = vlObservers[..]
for voObserver in vlNewObservers
do (voObserver)->
voObserver.notifyObserver aoNotification
return
@public registerMediator: FuncG(MediatorInterface),
default: (aoMediator)->
vsName = aoMediator.getMediatorName()
# Do not allow re-registration (you must removeMediator first).
if @[iphMediatorMap][vsName]?
return
aoMediator.initializeNotifier @[ipsMultitonKey]
# Register the Mediator for retrieval by name.
@[iphMediatorMap][vsName] = aoMediator
# Get Notification interests, if any.
vlInterests = aoMediator.listNotificationInterests() ? []
if vlInterests.length > 0
voObserver = Module::Observer.new aoMediator.handleNotification, aoMediator
for vsInterest in vlInterests
do (vsInterest)=>
@registerObserver vsInterest, voObserver
# Alert the mediator that it has been registered.
aoMediator.onRegister()
return
@public addMediator: FuncG(MediatorInterface),
default: (args...)-> @registerMediator args...
@public retrieveMediator: FuncG(String, MaybeG MediatorInterface),
default: (asMediatorName)->
@[iphMediatorMap][asMediatorName] ? null
@public getMediator: FuncG(String, MaybeG MediatorInterface),
default: (args...)-> @retrieveMediator args...
@public removeMediator: FuncG(String, MaybeG MediatorInterface),
default: (asMediatorName)->
voMediator = @[iphMediatorMap][asMediatorName]
unless voMediator?
return null
# Get Notification interests, if any.
vlInterests = voMediator.listNotificationInterests()
# For every notification this mediator is interested in...
for vsInterest in vlInterests
do (vsInterest)=>
@removeObserver vsInterest, voMediator
# remove the mediator from the map
@[iphMediatorMap][asMediatorName] = undefined
delete @[iphMediatorMap][asMediatorName]
# Alert the mediator that it has been removed
voMediator.onRemove()
return voMediator
@public hasMediator: FuncG(String, Boolean),
default: (asMediatorName)->
@[iphMediatorMap][asMediatorName]?
@public initializeView: Function,
default: ->
@public init: FuncG(String),
default: (asKey)->
@super arguments...
if View[cphInstanceMap][asKey]
throw Error View::MULTITON_MSG
View[cphInstanceMap][asKey] = @
@[ipsMultitonKey] = asKey
@[iphMediatorMap] = {}
@[iphObserverMap] = {}
@initializeView()
return
@initialize()