Giter VIP home page Giter VIP logo

molecule's Introduction

License Pharo 11 CI Pharo 12 CI

OpenSmock

Workshop and utilities to make applications, specialy user interfaces (UI), in Pharo.

Getting Started

Installing OpenSmock

To install all OpenSmock workshop on your Pharo image you can just execute the following script:

Metacello new
   baseline: 'OpenSmock';
   repository: 'github://OpenSmock/OpenSmock';
   load.

To install only OpenSmock core packages (no major dependencies) on your Pharo image you can just execute the following script:

Metacello new
   baseline: 'OpenSmock';
   repository: 'github://OpenSmock/OpenSmock';
   load: 'Core'.

Dependencies

Credits

  • Pierre Laborde - Initial work - labordep
  • Eric Le Pors - Initial work - ELePors
  • Brendan Landais - Development

License

This project is licensed under the MIT License - see the LICENSE file for details.

molecule's People

Contributors

elepors avatar eliott-guevel avatar labordep avatar landaisb avatar lisadoyen avatar nolwennfournier avatar nyan11 avatar plantec avatar samuel29590 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

molecule's Issues

Instanciate isn't the correct form

Instanciate is the french form of the verb, instantiate being the english form of the same verb.
Same goes for instanciation that must be changed to instantation.
Source,
it's also worth mentioning that no result comes up while searching for "instanciate" in a web navigator

Molecule-Test Failed

3 tests not work:

  • MolMySocketTest
    Missing class: MolMySocketComponentImpl, MolMyClientComponentImpl

  • MolMyTableTest
    Missing class: MolMyTableComponentImpl, MolMyUserComponentImpl

  • MolMyWarningSystemTest
    Missing class: MolMyWarnerComponentImpl, MolMyListenerComponentImpl

[IDE] bug - world menu - "No Components are running"

There is 2 bugs on molecule world menu.

When you start a new molecule component, the world menu doesn't update and still display "No Components are running".

molecule-bug-no-run
[molecule components is running but the world menu say other wise]

To reproduce

  • Run MolGPSExampleLauncher start. in the playground.
  • Then just click on molecule menu (menubar of current world). It should display "No Components are running".

It's also possible to trigger another similar bug.

  • Run MolGPSExampleLauncher start. in the playground.
  • Run MenubarMorph reset. in the playground. It should have corrected the bug.
  • Run MolGPSExampleLauncher stop. in the playground.
  • Then just click on molecule menu (menubar of current world). It should display "System is running Components".

Fix

It can be fixed by triggering the MenubarMorph reset..
bug-molecule-trigger-reset

To fix this issue MenubarMorph reset. should be trigger every time the number of components running passes from 0 to any > 0, and when the number of components go to any > 0 to 0.

It can be fix in the Molecule Package.
In MolHomeServices >>> activateComponent:named: at the end of the method, if we add the MenubarMorph reset.
In MolHomeServices >>> removeComponent:named: at the end of the method, if we add the MenubarMorph reset.

But, this solution will make MenubarMorph reset. for every component added or removed even when the number go from 5 to 6 for example. It should only trigger when the number of components change from 0 to any or any to 0.

Feature : Starting a Component Cluster

Starting automatically a Component Cluster composed by a set a Components Classes linked by a componentName.
For example :

MolUtils startComponentsCluster: aComponentList named: aComponentName.

This method start each components classes using "aComponentName" instead of #default key and map automatticaly each of them inside the cluster.

How to use multiple services and events providers ?

The problem appears when we are using multiple Components with the same contract definition (static), during the execution we are subscribe to multiple components and we are interesseted of uses same services contract from mutiple Component with different name.

For events, actually we are receiving all events but without the way to know the name of the emitter. A solution is to add the name of the emitter directly in the arguments of the events but this is not compatible with Component principles (do not modify used contract). For services, a solution is to create a services method manually which invoke the services from the targeted Component name, but this is uggly.

May be some solutions :

  • Services : Return a proxy when a service is called self myUsedComponentServices componentNamed: #componentB myServices
  • Events : get the name of the provider from the stack, as an example using thisContext to get the name of the emitter

Cannot add (but remove) some events producers

The point is to add some events producers like that :

MolComponentImpl>>forEvents: TMyEvents addProducer: #myProducer

And also to remove it with :

MolComponentImpl>>forEvents: anEventsTrait removeProducer: aComponentName => this method already exists

This is offer the capacity to dynamically change producers.

Bug : Cannot detect correctly if components are running

Bug - Code proposition :

MolComponentManager class

isRunningComponents
	<script:'self isRunningComponents inspect'>

	Default ifNotNil:[ | components |
		components := Default homeServices deployedComponents.
		components ifNil:[ ^false ].
		components valuesDo: [ :aDictionary | aDictionary notEmpty ifTrue:[ ^true ] ].
	].
	^false

#SearchFacade is missing when opening define a component menu

This class is missing :

MolWorld class>>openDefineComponentDialog

<script>
| searchClass list retValue |
list := SystemNavigation default allClasses select: [ :c | 
	        c isTrait not and: [ 
		        (c allSuperclasses includes: Object) and: [ c isComponentClass ] ] ].
searchClass := **SearchFacade** classSearchIn: list.
searchClass title: 'Select the Molecule Component to define'.
retValue := searchClass openModal.
^ retValue answer

Config :

  • Windows 10
  • Pharo-11.0.0+build.459

removing a producer on component also removes eventTrait

When you want to remove a producer on your component, you can use MolAbstractComponentImpl>>forEvents:removeProducer:

forEvents: anEventTrait removeProducer: aProducer

	| producers |
	producers := self eventsSubscribers at: anEventTrait.
	producers isArray 
		ifTrue: [ (self eventsSubscribers at: anEventTrait) remove: aProducer ]
		ifFalse: [ (self eventsSubscribers removeKey: anEventTrait ) ]

However, if you defined a single producer for an eventTrait (if it's not a list of producers), this method will remove the eventTrait key. Which will result in the component forgetting it consumes this kind of events although we just wanted it to stop using some producer.

Reproduce :
Here's an example with a component myComponent consuming SomeEvents events

myComponent getSomeEventsSubscriber. "works"
myComponent forEvents: SomeEvents useProducer: #someProducer.
myComponent forEvents: SomeEvents removeProducer: #someProducer.
myComponent getSomeEventsSubscriber. "bug"

Temporary solution :
replacing this portion of the code :
ifFalse: [ (self eventsSubscribers removeKey: anEventTrait ) ]
with :

ifFalse: [ producers = aProducer
	ifTrue: [ self eventsSubscribers at: anEventTrait put: #default ] ]

will check if the producer for the given eventTrait is the one we want to remove and if it's the case, it will set the value to the default one

Bug: different types can be used for the name of a component when creating or calling it

The normal way to name a component is to use a symbol. So when creating it we use a symbol and when we call it elsewhere we also use a symbol (see the following screenshot).

normal

The first bug is when creating a component, we can create it using a string and it works (see the following screenshot).

strange

The second bug is when we creating a component using a string and also using a string to call it. It doesn't work and the component isn't found (see the following screenshots).

string
string bug

Provided Events should be received after subscription enabling

This problem appear when a component which is already subscribing to an existing Events edit these providers list.

Test code that should be work (actually not) :

listenergetMyEventsSubscriber subscribe: listener.
listener forEvents: MyEvents useProducer: #newProvider. => not receiving, this is a bug

Centralize the default component name into a utility class

MolUtils class>>startComponent: aComponentClass
	"deploy, initialize and activate quickly a component and return the instance"
	
	^ self startComponent: aComponentClass named: #default

#default should be in a class enum to be used by anothers.
For example :
MolUtils class>>defaultComponentName

Putting an empty variable in a component's contract should fail

In Pharo 11, putting an instance variable into one of the parts that make a component's contract (i.e. consumed/producedComponentEvents, used/providedComponentServices) for a given Type automatically creates a get...Notifier method (as expected) in its implementations, but in this case leads to the creation of a getnilNotifier method. This getnilNotifier searches for notifiers at: nil, which isn't a trait that uses the MolComponentEvents trait.

Instead of this current behavior, the compilator should return an error when putting an empty instance variable into one or multiple parts of a component's contract.

Bug : Some component instances are still existing in the image after a cleanUp.

When you start a system with Molecule and then you stop this system, there are some times some component instances that are still existing in the image.
They are visible by looking in the Inspect all component instances menu of Molecule after an execution of a Molecule system.

issues

To reproduce

Lunch the GPS example, wait a little, and stop the example.

MolGPSExampleLauncher start.
"wait a little"
MolGPSExampleLauncher stop.

Then go on the Inspect all component instances menu of Molecule.
And here are the lost instances.

Fix

A solution to solve this problem is to do a garbage before opening this menu.

Smalltalk garbageCollect.

By doing that lost instances are remove from the Pharo image, and so they aren't visible from this menu. Furthermore, doing a garbage don't influence instances that are alive or using by a system, so this solution don't influence the menu's function.

Contract method not generated in Pharo 7

Since Pharo 7.0, contract methods are not automaticaly generated anymore. Probably a problem with Traits in Pharo 7.0 with Pragma.

Temporary solution :
Use MolComponentFactory defineComponent: YourComponentImpl for generate your contract methods from required Traits.

Tests : Subclass a of Component with another used Type

Write a test for set multiple type to a Component, and sub components which adding some others types :

  • ComponentA with TypeA and TypeB
  • Component B subclasse of ComponentA with Type C

=> Not possible because a component class should have only one type

Bug : undeploy component also remove existing components intances incorrectly

Undeploy component class remove existing components without apply remove life cycle :

removeDeployedComponent: aComponentClass
	deployedComponents isEmpty ifTrue: [^self].
	deployedComponents removeKey: aComponentClass ifAbsent:[^self] "This method remove all instance without apply the correct life cycle !"

Bug : ComponentConnector is not deleted when a Component is removed

This problem appear when I am using an old component instance as a classic class.

  • Start component
  • Stop component
  • User component API which call self componentConnector (for exemple get an EventsNotifier).

Code proposition :
MolComponentImpl>>

"component life cycle"
componentFlush

	self componentConnector release.
	self componentConnector: nil.

Remove forked component update when system annoucement are triggered

Molecule listening System Annoucement modification for Classes and Traits to update automatically components contracts.
The problem is theses updates should be forked because of when a Traits is added, updated or removed, the Traits changed notifications is triggerred before the Traits methods (and/or slots) are applied to the Class. So when Molecule check the contract content, regarding methods add/update/remove, the class changes are not here.

Class : MolComponentFactory>>initializeSystemAnnouncements and MolComponentFactory>>componentChanged: and MolComponentFactory>>contractChanged:

Bug : AlreadyPassivate and ComponentNotFound errors are raised during a ComponentManager>>cleanUp

Because of components are cleanup in a random order, component not found exceptions appears. Ignore theres errors during a cleanUp.

Code proposition for ComponentManager class :

cleanUp
	<script: 'self cleanUp'>
	| notifiers subscribers |

	"CleanUp and initialize the ComponentFactory"
	MolComponentFactory cleanUp.
	MolComponentFactory initialize.
	
	Default ifNil:[^self].
	Default locatorServices eventsSubscribers: nil.

	notifiers := MolEventNotifier allInstances.
	subscribers := MolEventSubscriber allInstances.

	"Ignore some Error during the cleanUp because the clean process can be different of the start order"
	[Default release] on: ComponentAlreadyPassivatedError, ComponentNotFoundError do:[ :e | "do nothing" ].

	Default := nil.
	notifiers do: [:n | n release].
	subscribers do: [:n | n release].

enhancement - Better world menu

I found two ways to improve the world menu for molecule.

Put molecule in the correct submenu

Maybe we should put molecule wordmenu in the Library worldmenu.
Roassal3 is present in the Library menu and not directly on the main MenuBar of the pharo world.

The description for Library is : "Third party tools and applications".
(The menu for Library is in package Morphic-Core > WorldState class side > LibraryWordMenuOn).

If we put the molecule menu under Library, we should add also an icon to it (for example the MolIcon).

worldmenu-roassal
[Roassal3 under Library]

better method naming

The current world menu for molecule doesn't seem to follow any clear structure in its methods names (inside the browser).

The world menu of molecule is present in 2 packages :

  • Molecule-IDE >>> MolWorld
  • Molecule-IDE-Incubators >>> MolWorldActionsMenu

The menu and the differents submenus methods are not explicit about their content and/or their position in the main menu. By making the methods names more explicits, we could edit the menu more rapidly in the future.

The Roassal3 world menu use a different convention to labels the methods : menu{position}{title/description}On.

I suggest we could rename the menus of molecule by :

in Molecule-IDE >>> MolWorld

  • menuCommandOn -> menu00moleculeOn
  • currentComponentSystem -> menu01currentComponentSystemOn
  • menuDebugOn -> menu02debugOn
  • componentManagerCleanUp -> menu04componentManagerCleanUpOn
  • menuExamplesOn -> menu05examplesOn
  • menuGithubOn -> menu06githubOn
  • menuReportBugOn -> menu07reportBugOn
    .
  • defineComponentOn -> debugMenu01defineComponentOn
  • toggleMolLogsOn -> debugMenu02toggleMolLogsOn
  • toggleDynamicContractUpdate -> debugMenu03toggleDynamicContractUpdate
  • inspectAllComponentInstances -> debugMenu04inspectAllComponentInstances
  • etc ...

in Molecule-IDE-Incubators >>> MolWorldActionsMenu

  • menuActionsOn -> menu03ActionsOn (or menu03IncubatorToolsOn)
  • menuInspectOn -> actionsMenu01inspectOn (+ Classify method as "menu - actions")
  • menuSearchOn -> actionsMenu02searchOn (+ Classify method as "menu - actions")
  • menuCreateOn -> actionsMenu03createOn (+ Classify method as "menu - actions")

browser-molecule
[Methods names of molecule are less explicit than Roassal3]
browser-roassal

Bug when remove an event producer named #default

testSubscribeAddAndRemoveProducerAndUnsubscribe
	
	| component |
	component := MolUtils startComponent: MolCompleteComponentImpl.
	component getMolUsedEventsSubscriber subscribe: self.
	
	component forEvents: MolUsedEvents addProducer: #default.
	component forEvents: MolUsedEvents removeProducer: #default. 
	
	component getMolUsedEventsSubscriber unsubscribe: self. "PLA => Bug here"

Cannot unsubscribe an originator to a receiver

When an originator remove his dependents for a component (on event) this remove cannot works.

Connection code :

MolEventSubscriber>>connectOriginator: componentName to: aComponent
	"Connect a component to event pipeline"

	self events allSelectors do: [ :event | | originator |
		
		originator := self originatorsLinks at: componentName.
		originator ifNil: [ ^ self error: 'Component originator is nil' ].
		originator when: event send: event to: aComponent.
	].

Deconnection code (not working):

MolEventSubscriber>>disconnectOriginator: componentName from: aComponent
	"private method, do not use directly"
	
	self events allSelectors do: [ :event | | originator |

		originator := self originatorsLinks at: componentName.
		originator ifNil: [ ^ self error: 'Component originator is nil' ].
		originator removeActionsWithReceiver: aComponent forEvent: event.
	]

Exception on building contextual menu (right click)

UseCase: On System browser, select a package, do not select any class, and perform a right click to open contextual menu.

Exception on MolCmdCommand - canBeExecutedInContext:

Array(Object)>>errorSubscriptBounds:
Array(Object)>>at:
MolDefineComponentCmdCommand class(MolCmdCommand class)>>canBeExecutedInContext:
ClyFullBrowserClassContext(CmdToolContext)>>allowsExecutionOf:
CmdContextMenuActivation(CmdCommandActivationStrategy)>>isActiveInContext:
CmdCommandActivator>>canExecuteCommand
CmdCommandActivator>>buildContextMenu:
CmdCommandMenuItem>>buildContextMenu:
[ :each | each buildContextMenu: submenu ] in MolCmdMenuGroup(CmdMenuGroup)>>buildContextSubMenuIn: in Block: [ :each | each buildContextMenu: submenu ]
SortedCollection(OrderedCollection)>>do:
MolCmdMenuGroup(CmdMenuGroup)>>buildContextSubMenuIn:
MolCmdMenuGroup(CmdMenuGroup)>>buildContextMenu:
MolCmdMenuGroup>>buildContextMenu:
[ :each | each buildContextMenu: aMenu ] in CmdRootMenuGroup(CmdMenuGroup)>>inlineContextMenuItemsInto: in Block: [ :each | each buildContextMenu: aMenu ]
SortedCollection(OrderedCollection)>>do:
CmdRootMenuGroup(CmdMenuGroup)>>inlineContextMenuItemsInto:
CmdRootMenuGroup(CmdMenuGroup)>>buildContextMenu:
CmdMenu>>buildContextMenuFor:
CmdContextMenuActivation class(CmdMenuCommandActivationStrategy class)>>buildContextMenuFor:inContext:
ClyQueryViewMorph>>menuColumn:row:
ClyExpandedDataSource(ClyDataSource)>>menuColumn:row:
FTTableMorph>>showMenuForIndex:
FTTableMorph>>showMenuForPosition:
FTTableMorph>>click:
MouseClickState>>click
MouseClickState>>handleEvent:from:
HandMorph>>handleEvent:
[
(morphicWorld activeHand isNotNil and: [ anEvent hand isNotNil ]) ifTrue: [
morphicWorld activeHand handleEvent: anEvent
]
] in OSWindowMorphicEventHandler>>dispatchMorphicEvent: in Block: [...
WorldState>>runStepMethodsIn:
WorldMorph>>runStepMethods

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.