Skip to content

Commit

Permalink
Trait semantics change.
Browse files Browse the repository at this point in the history
This commit introduces an incompatibility in the object model. Before this commit, traits were stored in a list and a really inefficient algorithm was used for finding conflicts and dispatching on objects. Further examination noted that since no conflicts can exist at any point in the composite objects slot table without explicit resolution (i.e., pick a different name for one of the items), then it is actually unnecessary to keep a list of items. Rather, we can add the items to our objects slot table. This does hinder removal of a trait once a composite object is built, but I believe this to be a minor issue. Presently we add trait Block objects *ONLY* to the slot table of the composite object. Should you care to transfer other types of state (i.e., a non-Block type) then you must do so manually. I would strongly advise not doing that however. Traits should be independent of state, and only carry behaviour.
  • Loading branch information
jeremytregunna committed Jan 24, 2012
1 parent e2d4e4f commit 9ffcb05
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 36 deletions.
45 changes: 13 additions & 32 deletions wee/object.cpp
Expand Up @@ -67,34 +67,18 @@ namespace Acute

if(implements(p.first, result))
throw SlotExistsError(p.first, result);
}

traits.push_back(trait);
Object* val = p.second;
if(val->object_name() == "Block")
// Skip any non-Block objects
add_slot(p.first, val);
}
}

// We don't want any conflicts. Returns true if we already implement name.
bool Object::implements(const std::string& name, Object*& obj)
{
SlotTable::iterator it;

for(auto t : traits)
{
// When we find that one of our traits already implements a given slot,
// we should through an exception.
SlotTable& st = t->slot_table();
it = st.find(name);
if(it != st.end())
{
obj = t;
return true;
}
}

it = slots.find(name);
if(it != slots.end())
return true;

return false;
return slots.find(name) == slots.end();
}

void Object::receive(Object* ctx)
Expand All @@ -121,18 +105,15 @@ namespace Acute

Object* Object::lookup(const std::string str, Object*& slot_context)
{
Object* value = NULL;

if(local_lookup(str, value, slot_context))
return value;
Object* value = nullptr;

for(auto t : traits)
{
if(t->local_lookup(str, value, slot_context))
return value;
}
local_lookup(str, value, slot_context);
// TODO:
// Invoke a catch-all "missing method" callback if available. This will allow our users to
// implement their own inheritance model if they so choose, and better yet, isolate it to
// their own library code.

return NULL;
return value;
}

Object* Object::perform(Object* locals, Message* msg)
Expand Down
6 changes: 2 additions & 4 deletions wee/object.hpp
Expand Up @@ -76,7 +76,8 @@ namespace Acute
void receive(Object*);

// Look up a slot
Object* lookup(const std::string str, Object*& slot_context);
bool local_lookup(const std::string, Object*&, Object*&);
Object* lookup(const std::string, Object*&);
Object* perform(Object*, Message*);
Object* forward(Object*, Message*);
Object* activate(Object*, Object*, Message*, Object*);
Expand All @@ -97,9 +98,6 @@ namespace Acute
// message sending and message receiving.
Mailbox* mailbox;

protected:
bool local_lookup(const std::string, Object*&, Object*&);

private:
bool implements(const std::string&, Object*& obj);
};
Expand Down

0 comments on commit 9ffcb05

Please sign in to comment.