Skip to content

Commit 581d795

Browse files
committed
Initial commit
0 parents  commit 581d795

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+4200
-0
lines changed

LICENSE

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
* PureMVC MultiCore Framework for Go - Copyright © 2019 Saad Shams
2+
* PureMVC - Copyright © 2019 Futurescale, Inc.
3+
* All rights reserved.
4+
5+
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6+
7+
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8+
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9+
* Neither the name of Futurescale, Inc., PureMVC.org, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10+
11+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
## [PureMVC](http://puremvc.github.com/) Go MultiCore Framework
2+
3+
PureMVC is a lightweight framework for creating applications based upon the classic [Model-View-Controller](http://en.wikipedia.org/wiki/Model-view-controller) design meta-pattern. It supports [modular programming](http://en.wikipedia.org/wiki/Modular_programming) through the use of [Multiton](http://en.wikipedia.org/wiki/Multiton) Core actors instead of the [Singletons](http://en.wikipedia.org/wiki/Singleton_pattern) used in the [Standard](https://github.com/PureMVC/puremvc-swift-standard-framework/wiki) Version.
4+
5+
* [API Docs]()
6+
* [Unit Tests](http://puremvc.org/pages/images/screenshots/PureMVC-Shot-Go-Multicore-UnitTests.png)
7+
8+
## Utilities
9+
* [Pipes](https://github.com/PureMVC/puremvc-go-util-pipes/wiki)
10+
11+
## Platforms / Technologies
12+
* [FreeBSD](https://en.wikipedia.org/wiki/FreeBSD)
13+
* [Linux](https://en.wikipedia.org/wiki/Linux)
14+
* [MacOS](https://en.wikipedia.org/wiki/MacOS)
15+
* [Windows](https://en.wikipedia.org/wiki/Microsoft_Windows)
16+
17+
## Status
18+
Production - [Version 1.0](https://github.com/PureMVC/puremvc-go-multicore-framework/blob/master/VERSION)
19+
20+
## License
21+
* PureMVC MultiCore Framework for Go - Copyright © 2019 [Saad Shams](https://www.linkedin.com/in/muizz/)
22+
* PureMVC - Copyright © 2019 [Futurescale, Inc.](http://futurescale.com/)
23+
* All rights reserved.
24+
25+
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
26+
27+
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
28+
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
29+
* Neither the name of Futurescale, Inc., PureMVC.org, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
30+
31+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

VERSION

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
PureMVC MultiCore Framework for Go
2+
--------------------------------------------------------------------------
3+
Release Date: 04/25/19
4+
Platform: Go
5+
Version: 1
6+
Revision: 0
7+
Minor: 0
8+
Author: Saad Shams <saad.shams@puremvc.org>
9+
--------------------------------------------------------------------------
10+
1.0 - Initial release.

src/core/controller/Controller.go

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
//
2+
// Controller.go
3+
// PureMVC Go Multicore
4+
//
5+
// Copyright(c) 2019 Saad Shams <saad.shams@puremvc.org>
6+
// Your reuse is governed by the Creative Commons Attribution 3.0 License
7+
//
8+
9+
package controller
10+
11+
import (
12+
"github.com/puremvc/puremvc-go-multicore-framework/src/core/view"
13+
"github.com/puremvc/puremvc-go-multicore-framework/src/interfaces"
14+
"github.com/puremvc/puremvc-go-multicore-framework/src/patterns/observer"
15+
"sync"
16+
)
17+
18+
/**
19+
A Multiton `IController` implementation.
20+
21+
In PureMVC, the `Controller` class follows the
22+
'Command and Controller' strategy, and assumes these
23+
responsibilities:
24+
25+
* Remembering which `ICommand`s are intended to handle which `INotifications`.
26+
* Registering itself as an `IObserver` with the `View` for each `INotification` that it has an `ICommand` mapping for.
27+
* Creating a new instance of the proper `ICommand` to handle a given `INotification` when notified by the `View`.
28+
* Calling the `ICommand`'s `execute` method, passing in the `INotification`.
29+
30+
Your application must register `ICommands` with the
31+
Controller.
32+
33+
The simplest way is to subclass `Facade`,
34+
and use its `initializeController` method to add your
35+
registrations.
36+
*/
37+
type Controller struct {
38+
Key string // The Multiton Key for this Core
39+
commandMap map[string]func() interfaces.ICommand // Mapping of Notification names to funcs that returns `ICommand` Class instances
40+
commandMapMutex sync.RWMutex // Mutex for commandMap
41+
view interfaces.IView // Local reference to View
42+
}
43+
44+
var instanceMap = map[string]interfaces.IController{} // The Multiton Controller instanceMap.
45+
var instanceMapMutex sync.RWMutex // instanceMap Mutex
46+
47+
/**
48+
`Controller` Multiton Factory method.
49+
50+
- parameter key: multitonKey
51+
- parameter controllerFunc: reference that returns `IController`
52+
- returns: the Multiton instance
53+
*/
54+
func GetInstance(key string, controllerFunc func() interfaces.IController) interfaces.IController {
55+
instanceMapMutex.Lock()
56+
defer instanceMapMutex.Unlock()
57+
58+
if instanceMap[key] == nil {
59+
instanceMap[key] = controllerFunc()
60+
instanceMap[key].InitializeController()
61+
}
62+
return instanceMap[key]
63+
}
64+
65+
/**
66+
Initialize the Multiton `Controller` instance.
67+
68+
Called automatically by the GetInstance.
69+
70+
Note that if you are using a subclass of `View`
71+
in your application, you should *also* subclass `Controller`
72+
and override the `InitializeController` method in the
73+
following way:
74+
75+
func (self *MyController) InitializeController() {
76+
self.commandMap = map[string]func() interfaces.ICommand{}
77+
self.view = MyView.GetInstance(self.Key, func() interfaces.IView { return &MyView{Key: self.Key} })
78+
}
79+
*/
80+
func (self *Controller) InitializeController() {
81+
self.commandMap = map[string]func() interfaces.ICommand{}
82+
self.view = view.GetInstance(self.Key, func() interfaces.IView { return &view.View{Key: self.Key} })
83+
}
84+
85+
/**
86+
If an `ICommand` has previously been registered
87+
to handle a the given `INotification`, then it is executed.
88+
89+
- parameter note: an `INotification`
90+
*/
91+
func (self *Controller) ExecuteCommand(notification interfaces.INotification) {
92+
self.commandMapMutex.RLock()
93+
defer self.commandMapMutex.RUnlock()
94+
95+
var commandFunc = self.commandMap[notification.Name()]
96+
if commandFunc == nil {
97+
return
98+
}
99+
commandInstance := commandFunc()
100+
commandInstance.InitializeNotifier(self.Key)
101+
commandInstance.Execute(notification)
102+
}
103+
104+
/**
105+
Register a particular `ICommand` class as the handler
106+
for a particular `INotification`.
107+
108+
If an `ICommand` has already been registered to
109+
handle `INotification`s with this name, it is no longer
110+
used, the new `ICommand` is used instead.
111+
112+
The Observer for the new ICommand is only created if this the
113+
first time an ICommand has been regisered for this Notification name.
114+
115+
- parameter notificationName: the name of the `INotification`
116+
- parameter commandFunc: reference that returns `ICommand`
117+
*/
118+
func (self *Controller) RegisterCommand(notificationName string, commandFunc func() interfaces.ICommand) {
119+
self.commandMapMutex.Lock()
120+
defer self.commandMapMutex.Unlock()
121+
122+
if self.commandMap[notificationName] == nil {
123+
self.view.RegisterObserver(notificationName, &observer.Observer{Notify: self.ExecuteCommand, Context: self})
124+
}
125+
self.commandMap[notificationName] = commandFunc
126+
}
127+
128+
/**
129+
Check if a Command is registered for a given Notification
130+
131+
- parameter notificationName:
132+
- returns: whether a Command is currently registered for the given `notificationName`.
133+
*/
134+
func (self *Controller) HasCommand(notificationName string) bool {
135+
self.commandMapMutex.RLock()
136+
defer self.commandMapMutex.RUnlock()
137+
138+
return self.commandMap[notificationName] != nil
139+
}
140+
141+
/**
142+
Remove a previously registered `ICommand` to `INotification` mapping.
143+
144+
- parameter notificationName: the name of the `INotification` to remove the `ICommand` mapping for
145+
*/
146+
func (self *Controller) RemoveCommand(notificationName string) {
147+
self.commandMapMutex.Lock()
148+
defer self.commandMapMutex.Unlock()
149+
150+
if self.commandMap[notificationName] != nil {
151+
self.view.RemoveObserver(notificationName, self)
152+
delete(self.commandMap, notificationName)
153+
}
154+
}
155+
156+
/**
157+
Remove an IController instance
158+
159+
- parameter multitonKey: of IController instance to remove
160+
*/
161+
func RemoveController(key string) {
162+
instanceMapMutex.Lock()
163+
defer instanceMapMutex.Unlock()
164+
165+
delete(instanceMap, key)
166+
}

src/core/model/Model.go

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
//
2+
// Model.go
3+
// PureMVC Go Multicore
4+
//
5+
// Copyright(c) 2019 Saad Shams <saad.shams@puremvc.org>
6+
// Your reuse is governed by the Creative Commons Attribution 3.0 License
7+
//
8+
9+
package model
10+
11+
import (
12+
"github.com/puremvc/puremvc-go-multicore-framework/src/interfaces"
13+
"sync"
14+
)
15+
16+
/**
17+
A Multiton `IModel` implementation.
18+
19+
In PureMVC, the `Model` class provides
20+
access to model objects (Proxies) by named lookup.
21+
22+
The `Model` assumes these responsibilities:
23+
24+
* Maintain a cache of `IProxy` instances.
25+
* Provide methods for registering, retrieving, and removing `IProxy` instances.
26+
27+
Your application must register `IProxy` instances
28+
with the `Model`. Typically, you use an
29+
`ICommand` to create and register `IProxy`
30+
instances once the `Facade` has initialized the Core
31+
actors.
32+
*/
33+
type Model struct {
34+
Key string // The Multiton Key for this Core
35+
proxyMap map[string]interfaces.IProxy // Mapping of proxyNames to IProxy instances
36+
proxyMapMutex sync.RWMutex // Mutex for proxyMap
37+
}
38+
39+
var instanceMap = map[string]interfaces.IModel{} // The Multiton Model instanceMap.
40+
var instanceMapMutex sync.RWMutex // instanceMapMutex for thread safety
41+
42+
/**
43+
Initialize the `Model` instance.
44+
45+
Called automatically by the `GetInstance`, this
46+
is your opportunity to initialize the Multiton
47+
instance in your subclass without overriding the
48+
constructor.
49+
*/
50+
func (self *Model) InitializeModel() {
51+
self.proxyMap = map[string]interfaces.IProxy{}
52+
}
53+
54+
/**
55+
`Model` Multiton Factory method.
56+
57+
- parameter key: multitonKey
58+
- parameter modelFunc: reference that returns `IModel`
59+
- returns: the instance returned by the passed modelFunc
60+
*/
61+
func GetInstance(key string, modelFunc func() interfaces.IModel) interfaces.IModel {
62+
instanceMapMutex.Lock()
63+
defer instanceMapMutex.Unlock()
64+
65+
if instanceMap[key] == nil {
66+
instanceMap[key] = modelFunc()
67+
instanceMap[key].InitializeModel()
68+
}
69+
return instanceMap[key]
70+
}
71+
72+
/**
73+
Register an `IProxy` with the `Model`.
74+
75+
- parameter proxy: an `IProxy` to be held by the `Model`.
76+
*/
77+
func (self *Model) RegisterProxy(proxy interfaces.IProxy) {
78+
self.proxyMapMutex.Lock()
79+
defer self.proxyMapMutex.Unlock()
80+
81+
proxy.InitializeNotifier(self.Key)
82+
self.proxyMap[proxy.GetProxyName()] = proxy
83+
proxy.OnRegister()
84+
}
85+
86+
/**
87+
Retrieve an `IProxy` from the `Model`.
88+
89+
- parameter proxyName:
90+
- returns: the `IProxy` instance previously registered with the given `proxyName`.
91+
*/
92+
func (self *Model) RetrieveProxy(proxyName string) interfaces.IProxy {
93+
self.proxyMapMutex.RLock();
94+
defer self.proxyMapMutex.RUnlock()
95+
96+
return self.proxyMap[proxyName]
97+
}
98+
99+
/**
100+
Remove an `IProxy` from the `Model`.
101+
102+
- parameter proxyName: name of the `IProxy` instance to be removed.
103+
- returns: the `IProxy` that was removed from the `Model`
104+
*/
105+
func (self *Model) RemoveProxy(proxyName string) interfaces.IProxy {
106+
self.proxyMapMutex.Lock()
107+
defer self.proxyMapMutex.Unlock()
108+
109+
var proxy = self.proxyMap[proxyName]
110+
if proxy != nil {
111+
delete(self.proxyMap, proxyName)
112+
proxy.OnRemove()
113+
}
114+
return proxy
115+
}
116+
117+
/**
118+
Check if a Proxy is registered
119+
120+
- parameter proxyName:
121+
- returns: whether a Proxy is currently registered with the given `proxyName`.
122+
*/
123+
func (self *Model) HasProxy(proxyName string) bool {
124+
self.proxyMapMutex.RLock()
125+
defer self.proxyMapMutex.RUnlock()
126+
127+
return self.proxyMap[proxyName] != nil
128+
}
129+
130+
/**
131+
Remove an IModel instance
132+
133+
- parameter multitonKey: of IModel instance to remove
134+
*/
135+
func RemoveModel(key string) {
136+
instanceMapMutex.Lock()
137+
defer instanceMapMutex.Unlock()
138+
139+
delete(instanceMap, key)
140+
}

0 commit comments

Comments
 (0)