Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/Object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ namespace archetype {
return attributes_.count(attribute_id) > 0 or (p and p->hasAttribute(attribute_id));
}

bool Object::hasLocalAttribute(int attribute_id) const {
return attributes_.count(attribute_id) > 0;
}

Value Object::getAttributeValue(int attribute_id) const {
auto where = attributes_.find(attribute_id);
if (where != attributes_.end()) {
Expand Down
1 change: 1 addition & 0 deletions src/Object.hh
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ namespace archetype {
ObjectPtr parent() const;

bool hasAttribute(int attribute_id) const;
bool hasLocalAttribute(int attribute_id) const;
Value getAttributeValue(int attribute_id) const;
void setAttribute(int attribute_id, Expression expr);
void setAttribute(int attribute_id, Value val);
Expand Down
37 changes: 37 additions & 0 deletions src/TestObject.cc
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,47 @@ namespace archetype {
ARCHETYPE_TEST_EQUAL(actual2, expected2);
}

void TestObject::testReadDoesNotMutate_() {
ObjectPtr subject = Universe::instance().defineNewObject();
Universe::instance().assignObjectIdentifier(subject, "subject");
int ghost_id = Universe::instance().Identifiers.index("ghost");

ARCHETYPE_TEST(not subject->hasAttribute(ghost_id));

Expression expr = make_expr_from_str("subject.ghost");
Value val = expr->evaluate()->valueConversion();
ARCHETYPE_TEST(not val->isDefined());

ARCHETYPE_TEST(not subject->hasAttribute(ghost_id));

expr->evaluate();
expr->evaluate();
ARCHETYPE_TEST(not subject->hasAttribute(ghost_id));

ObjectPtr animal = Universe::instance().defineNewObject();
animal->setPrototype(true);
Universe::instance().assignObjectIdentifier(animal, "animal");
int legs_id = Universe::instance().Identifiers.index("legs");
animal->setAttribute(legs_id, Value(new NumericValue(4)));

ObjectPtr dog = Universe::instance().defineNewObject(animal->id());
Universe::instance().assignObjectIdentifier(dog, "dog");

ARCHETYPE_TEST(dog->hasAttribute(legs_id));
ARCHETYPE_TEST(not dog->hasLocalAttribute(legs_id));

Expression inherited = make_expr_from_str("dog.legs");
Value inherited_val = inherited->evaluate()->numericConversion();
ARCHETYPE_TEST_EQUAL(inherited_val->getNumber(), 4);

ARCHETYPE_TEST(not dog->hasLocalAttribute(legs_id));
}

void TestObject::runTests_() {
testObjects_();
testInheritance_();
testMethods_();
testMessagePassing_();
testReadDoesNotMutate_();
}
}
1 change: 1 addition & 0 deletions src/TestObject.hh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace archetype {
void testInheritance_();
void testMethods_();
void testMessagePassing_();
void testReadDoesNotMutate_();
protected:
virtual void runTests_() override;
public:
Expand Down
6 changes: 1 addition & 5 deletions src/Value.cc
Original file line number Diff line number Diff line change
Expand Up @@ -350,14 +350,10 @@ namespace archetype {

Value AttributeValue::dereference_() const {
ObjectPtr obj = Universe::instance().getObject(objectId_);
if (not obj) {
if (not obj or not obj->hasAttribute(attributeId_)) {
Comment thread
gitosaurus marked this conversation as resolved.
return Value{new UndefinedValue};
}
Comment thread
gitosaurus marked this conversation as resolved.

if (not obj->hasAttribute(attributeId_)) {
obj->setAttribute(attributeId_, Value{new UndefinedValue});
}

ContextScope c;
c->selfObject = obj;
return obj->getAttributeValue(attributeId_);
Expand Down
Loading