mirror of
https://github.com/evennia/evennia.git
synced 2026-03-30 20:47:17 +02:00
OBS: Run migrate! Made exit's destination into a database field for performance. Fixed a too greedy @reload that caused ContentTypes to loose information. Resolves issue 157.
Migrate with: "python manage.py migrate"
This commit is contained in:
parent
0cff54f136
commit
6c53ec2bdb
11 changed files with 227 additions and 84 deletions
|
|
@ -70,7 +70,7 @@ class ExitHandler(object):
|
|||
|
||||
# use exits to create searchable "commands" for the cmdhandler
|
||||
for exi in (exi for exi in location.contents
|
||||
if exi.has_attribute('_destination')):
|
||||
if exi.destination):
|
||||
if exi.id in self.cached_exit_cmds:
|
||||
# retrieve from cache
|
||||
exit_cmdset.add(self.cached_exit_cmds[exi.id])
|
||||
|
|
@ -81,7 +81,7 @@ class ExitHandler(object):
|
|||
cmd.obj = exi
|
||||
if exi.aliases:
|
||||
cmd.aliases = exi.aliases
|
||||
cmd.destination = exi.attr('_destination')
|
||||
cmd.destination = exi.destination
|
||||
exit_cmdset.add(cmd)
|
||||
self.cached_exit_cmds[exi.id] = cmd
|
||||
return exit_cmdset
|
||||
|
|
|
|||
|
|
@ -0,0 +1,113 @@
|
|||
# encoding: utf-8
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
from src.objects.models import ObjectDB
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding field 'ObjectDB.db_destination'
|
||||
db.add_column('objects_objectdb', 'db_destination', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='destinations_set', null=True, to=orm['objects.ObjectDB']), keep_default=False)
|
||||
|
||||
# move all exits to the new property
|
||||
for exi in ObjectDB.objects.get_objs_with_attr('_destination'):
|
||||
exi.destination = exi.db._destination
|
||||
exi.del_attribute('_destination')
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting field 'ObjectDB.db_destination'
|
||||
db.delete_column('objects_objectdb', 'db_destination_id')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'objects.alias': {
|
||||
'Meta': {'object_name': 'Alias'},
|
||||
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['objects.ObjectDB']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
},
|
||||
'objects.nick': {
|
||||
'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'Nick'},
|
||||
'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['objects.ObjectDB']"}),
|
||||
'db_real': ('django.db.models.fields.TextField', [], {}),
|
||||
'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
},
|
||||
'objects.objattribute': {
|
||||
'Meta': {'object_name': 'ObjAttribute'},
|
||||
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['objects.ObjectDB']"}),
|
||||
'db_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
},
|
||||
'objects.objectdb': {
|
||||
'Meta': {'object_name': 'ObjectDB'},
|
||||
'db_cmdset_storage': ('django.db.models.fields.TextField', [], {'null': 'True'}),
|
||||
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'db_destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destinations_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||
'db_home': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'homes_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'db_location': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locations_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||
'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
|
||||
'db_player': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']", 'null': 'True', 'blank': 'True'}),
|
||||
'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
},
|
||||
'players.playerdb': {
|
||||
'Meta': {'object_name': 'PlayerDB'},
|
||||
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['objects.ObjectDB']", 'null': 'True'}),
|
||||
'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
|
||||
'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['objects']
|
||||
|
|
@ -217,6 +217,9 @@ class ObjectDB(TypedObject):
|
|||
# a safety location, this usually don't change much.
|
||||
db_home = models.ForeignKey('self', related_name="homes_set",
|
||||
blank=True, null=True)
|
||||
# destination of this object - primarily used by exits.
|
||||
db_destination = models.ForeignKey('self', related_name="destinations_set",
|
||||
blank=True, null=True)
|
||||
# database storage of persistant cmdsets.
|
||||
db_cmdset_storage = models.TextField(null=True)
|
||||
|
||||
|
|
@ -325,6 +328,7 @@ class ObjectDB(TypedObject):
|
|||
def location_del(self):
|
||||
"Deleter. Allows for del self.location"
|
||||
self.db_location = None
|
||||
self.save()
|
||||
location = property(location_get, location_set, location_del)
|
||||
|
||||
# home property (wraps db_home)
|
||||
|
|
@ -362,8 +366,48 @@ class ObjectDB(TypedObject):
|
|||
def home_del(self):
|
||||
"Deleter. Allows for del self.home."
|
||||
self.db_home = None
|
||||
self.save()
|
||||
home = property(home_get, home_set, home_del)
|
||||
|
||||
# destination property (wraps db_destination)
|
||||
#@property
|
||||
def destination_get(self):
|
||||
"Getter. Allows for value = self.destination."
|
||||
dest = self.db_destination
|
||||
if dest:
|
||||
return dest.typeclass(dest)
|
||||
return None
|
||||
#@destination.setter
|
||||
def destination_set(self, destination):
|
||||
"Setter. Allows for self.destination = destination"
|
||||
try:
|
||||
if destination == None or type(destination) == ObjectDB:
|
||||
# destination is None or a valid object
|
||||
dest = destination
|
||||
elif ObjectDB.objects.dbref(destination):
|
||||
# destination is a dbref; search
|
||||
dest = ObjectDB.objects.dbref_search(destination)
|
||||
if dest and hasattr(dest,'dbobj'):
|
||||
dest = dest.dbobj
|
||||
else:
|
||||
dest = destination.dbobj
|
||||
else:
|
||||
dest = destination.dbobj
|
||||
self.db_destination = dest
|
||||
self.save()
|
||||
except Exception:
|
||||
string = "Cannot set destination: "
|
||||
string += "%s is not a valid destination."
|
||||
self.msg(string % destination)
|
||||
logger.log_trace(string)
|
||||
raise
|
||||
#@destination.deleter
|
||||
def destination_del(self):
|
||||
"Deleter. Allows for del self.destination"
|
||||
self.db_destination = None
|
||||
self.save()
|
||||
destination = property(destination_get, destination_set, destination_del)
|
||||
|
||||
#@property for consistent aliases access throughout Evennia
|
||||
#@aliases.setter
|
||||
def aliases_set(self, aliases):
|
||||
|
|
@ -462,10 +506,10 @@ class ObjectDB(TypedObject):
|
|||
def exits_get(self):
|
||||
"""
|
||||
Returns all exits from this object, i.e. all objects
|
||||
at this location having the property _destination.
|
||||
at this location having the property destination != None.
|
||||
"""
|
||||
return [exi for exi in self.contents
|
||||
if exi.has_attribute('_destination')]
|
||||
if exi.destination]
|
||||
exits = property(exits_get)
|
||||
|
||||
|
||||
|
|
@ -589,8 +633,8 @@ class ObjectDB(TypedObject):
|
|||
Moves this object to a new location.
|
||||
|
||||
destination: (Object) Reference to the object to move to. This
|
||||
can also be an exit object, in which case the _destination
|
||||
attribute is used as destination.
|
||||
can also be an exit object, in which case the destination
|
||||
property is used as destination.
|
||||
quiet: (bool) If true, don't emit left/arrived messages.
|
||||
emit_to_obj: (Object) object to receive error messages
|
||||
"""
|
||||
|
|
@ -601,9 +645,9 @@ class ObjectDB(TypedObject):
|
|||
if not destination:
|
||||
emit_to_obj.msg("The destination doesn't exist.")
|
||||
return
|
||||
if destination.has_attribute('_destination'):
|
||||
if destination.destination:
|
||||
# traverse exits
|
||||
destination = destination.get_attribute('_destination')
|
||||
destination = destination.destination
|
||||
|
||||
# Before the move, call eventual pre-commands.
|
||||
try:
|
||||
|
|
@ -689,8 +733,7 @@ class ObjectDB(TypedObject):
|
|||
"""
|
||||
for out_exit in self.exits:
|
||||
out_exit.delete()
|
||||
for in_exit in \
|
||||
ObjectDB.objects.get_objs_with_attr_match('_destination', self):
|
||||
for in_exit in ObjectDB.objects.filter(db_destination=self):
|
||||
in_exit.delete()
|
||||
|
||||
def clear_contents(self):
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ class Object(TypeClass):
|
|||
loc_name = self.location.name
|
||||
dest_name = destination.name
|
||||
string = "%s is leaving %s, heading for %s."
|
||||
self.location.emit_to_contents(string % (name, loc_name, dest_name), exclude=self)
|
||||
self.location.msg_contents(string % (name, loc_name, dest_name), exclude=self)
|
||||
|
||||
def announce_move_to(self, source_location):
|
||||
"""
|
||||
|
|
@ -143,7 +143,7 @@ class Object(TypeClass):
|
|||
# This was created from nowhere and added to a player's
|
||||
# inventory; it's probably the result of a create command.
|
||||
string = "You now have %s in your possession." % name
|
||||
self.location.emit_to(string)
|
||||
self.location.msg(string)
|
||||
return
|
||||
|
||||
src_name = "nowhere"
|
||||
|
|
@ -151,7 +151,7 @@ class Object(TypeClass):
|
|||
if source_location:
|
||||
src_name = source_location.name
|
||||
string = "%s arrives to %s from %s."
|
||||
self.location.emit_to_contents(string % (name, loc_name, src_name), exclude=self)
|
||||
self.location.msg_contents(string % (name, loc_name, src_name), exclude=self)
|
||||
|
||||
|
||||
def at_after_move(self, source_location):
|
||||
|
|
@ -203,7 +203,7 @@ class Object(TypeClass):
|
|||
if content == pobject:
|
||||
continue
|
||||
name = content.name
|
||||
if content.attr('_destination'):
|
||||
if content.destination:
|
||||
exits.append(name)
|
||||
elif content.has_player:
|
||||
users.append(name)
|
||||
|
|
@ -360,12 +360,12 @@ class Exit(Object):
|
|||
"""
|
||||
This is the base exit object - it connects a location
|
||||
to another. What separates it from other objects
|
||||
is that it has the '_destination' attribute defined.
|
||||
Note that _destination is the only identifier to
|
||||
separate an exit from normal objects, so if _destination
|
||||
is that it has the 'destination' property defined.
|
||||
Note that property is the only identifier to
|
||||
separate an exit from normal objects, so if the property
|
||||
is removed, it will be treated like any other object. This
|
||||
also means that any object can be made an exit by setting
|
||||
the attribute _destination to a valid location
|
||||
the property destination to a valid location
|
||||
('Quack like a duck...' and so forth).
|
||||
"""
|
||||
def basetype_setup(self):
|
||||
|
|
@ -379,13 +379,17 @@ class Exit(Object):
|
|||
|
||||
def at_object_creation(self):
|
||||
"""
|
||||
An example just for show; the _destination attribute
|
||||
An example just for show; the destination property
|
||||
is usually set at creation time, not as part of the class
|
||||
definition (unless you want an entire class of exits
|
||||
all leadning to the same hard-coded place ...)
|
||||
"""
|
||||
# this is what makes it an exit
|
||||
self.attr("_destination", "None")
|
||||
# having destination != None is what makes it an exit
|
||||
# (what's set here won't last)
|
||||
if self.location:
|
||||
self.destination = self.location
|
||||
else:
|
||||
self.destination = 2 # use limbo as a failsafe
|
||||
|
||||
def at_object_delete(self):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue