Simpleton Programming
To create a simpleton, subclass class Simpleton
to make a public
class and write a
public void process()
method.
Compile the simpleton and put its class file in the
datamangerstartup directory.
The kernel periodically searches there for any new class files
and loads them into the system.
Whenever there is a free thread
it will create an instance of the simpleton
then call the instance's process()
method.
The simpleton will then run in its own thread and will live
until its process()
method exits or the current session ends.
Normally, a simpleton will first do a
Pool.getDefaultPool()
to get a reference to the default pool
then it will do a search()
on the default pool
to discover some entities it wants to work with.
Once it has some entities, it can create new ones,
link them to each other or to old entities,
and unlink entities.
It can also subscribe to entities or pools, unsubscribe from them,
and search pools.
Simpletons that subscribe to an EventGenerator
must implement the EventHandler
interface.
Their handle()
method will execute in a separate thread
(assigned by the kernel)
if the subscribed EventGenerator
ever generates an event
matching the subscription constraint.
The thread executing the handle()
method
can then pass on that updated information
to the thread executing the process()
method
via a shared synchronized data structure.
The simpleton may also create a separate handler,
which it delegates various event subscriptions to.
Simpleton Types
KnownSpace has many parts, and each part can call for different kinds of simpletons.
-
Some simpletons want their data right away,
to do some calculation immediately.
For example, user interface simpletons want all the entities right away so that they can display them.
Such simpletons should usesearch()
on the default pool and save all the entity references returned, then work on each one in succession. -
Others just want to be notified whenever any new entities enter the system,
when any new attributes are added to an entity,
or when any entity's attributes change.
For example, data model simpletons have to track changes to the entities so that they can respond by readjusting estimates of entity desirability or relationship. Similarly, user model simpletons have to know when new user interface events enter the system so that they can integrate the new information into the system's model of its user.
Such simpletons should usesubscribe()
andunsubscribe()
on the default pool to register and unregister interest in various entity events. They will spend most of their time sleeping. -
And still others just wander around and don't care.
For example, many kernel simpletons and several collector simpletons just do what needs done whenever they have a chance and nothing much else is going on. They, typically, have to look at every entity eventually, either because they're things like entity purgers or because they're things like website monitors, but they don't have to look at any particular entity right now. They will make do with whatever they get.
Such simpletons will typically use a combination strategy of searching and subscribing. They will spend most of their time on low-priority tasks but will rarely sleep.
Normally, a simpleton should work on an entity, do some computations, perhaps involving other entities, then link some other entities to the entity, perhaps creating new ones, setting their values, then linking them and so on. Some of the entities that a simpleton might link to an entity can be simple marker entities saying that it's looked at that entity and doesn't want to see it again, or that it wants to look at the entity again sometime, or that it wants to mark the entity in some way so that other simpletons can do some more computation on that entity later.
Simpleton Structure
Most simpletons should do one job and then die. Simpletons should not be huge programs that live forever. Writing large simpletons takes longer, leads to more bugs, and is more inflexible than writing small simpletons. Changing a huge simpleton is a major task. Further, by breaking up the processing into small steps, any of those steps can be reused as part of some other process.
Simpleton applications should be an assembly line, with different simpletons doing small jobs on something so that in the end something big has been accomplished. Modifying such a program later means only modifying one or a few simpletons in the assembly line.
Simpletons should never be aware that other simpletons exist. If they ever need to communicate, they should do so only indirectly by generating events, or by storing and retrieving entity values. For example, if one simpleton wants to pass an entity to another simpleton it should add the entity to an entity list and store the list as the value of some entity that is already linked into the set of linked entities. Direct simpleton communication can lead to undefined kernel behavior.
When manipulating an entity it's important to remember that any other
simpleton may also be manipulating the same entity at the same time.
The kernel performs every Entity
method atomically
(including attach()
and detach()
),
but between any two of your simpleton's method executions on an entity,
some other simpleton may change that entity's state.
The kernel does not yet support a permissions model,
nor multiple pools, nor a transaction model,
so once you add()
an entity to the default pool,
anyone may change it.
Thus, the following pseudocode may not do what you think:
if (entity1.getValue() != 0)
entity1.setValue(1/entity1.getValue());
If entity1
is already in the pool
then it can be found by other simpletons,
thus they can alter its state.
So by the time execution reaches the second getValue()
some other simpleton may have set its value to zero.