summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Smith <bruce@nanorex.com>2008-09-05 20:56:53 +0000
committerBruce Smith <bruce@nanorex.com>2008-09-05 20:56:53 +0000
commit8aff664f2ded4d672a1c6b83837554bc8021b039 (patch)
tree839768ef86748bbe182f7eba30c56311ab39075c
parent9ab39c30096de2c08110928c6ff61f4bb3895388 (diff)
downloadnanoengineer-theirix-8aff664f2ded4d672a1c6b83837554bc8021b039.tar.gz
nanoengineer-theirix-8aff664f2ded4d672a1c6b83837554bc8021b039.zip
fix export command table for recent command changes
-rwxr-xr-xcad/src/command_support/Command.py2
-rw-r--r--cad/src/command_support/EditCommand.py1
-rw-r--r--cad/src/command_support/baseCommand.py23
-rw-r--r--cad/src/dna/command_support/BreakOrJoinStrands_Command.py7
-rw-r--r--cad/src/foundation/FeatureDescriptor.py65
-rw-r--r--cad/src/operations/ops_debug.py23
-rwxr-xr-xcad/src/prototype/test_commands.py1
-rw-r--r--cad/src/temporary_commands/TemporaryCommand.py1
8 files changed, 75 insertions, 48 deletions
diff --git a/cad/src/command_support/Command.py b/cad/src/command_support/Command.py
index 8baacdd09..e0c9351dd 100755
--- a/cad/src/command_support/Command.py
+++ b/cad/src/command_support/Command.py
@@ -83,6 +83,7 @@ class anyCommand(baseCommand, StateMixin):
from utilities.constants import CL_ABSTRACT
command_level = CL_ABSTRACT
# command_level is not yet documented, part of command stack refactoring
+ __abstract_command_class = True
command_parent = None
# Subclasses should set this to the commandName of the parent command
@@ -357,6 +358,7 @@ class basicCommand(anyCommand):
featurename = "Undocumented Command"
from utilities.constants import CL_ABSTRACT
command_level = CL_ABSTRACT
+ __abstract_command_class = True
command_can_be_suspended = True # good default value for most commands [bruce 071011]
diff --git a/cad/src/command_support/EditCommand.py b/cad/src/command_support/EditCommand.py
index 10ba4bcf6..8da0a8104 100644
--- a/cad/src/command_support/EditCommand.py
+++ b/cad/src/command_support/EditCommand.py
@@ -79,6 +79,7 @@ class EditCommand(Select_Command):
featurename = "Undocumented Edit Command" # default wiki help featurename
from utilities.constants import CL_ABSTRACT
command_level = CL_ABSTRACT
+ __abstract_command_class = True
propMgr = None
flyoutToolbar = None
diff --git a/cad/src/command_support/baseCommand.py b/cad/src/command_support/baseCommand.py
index 2c1797c34..621152511 100644
--- a/cad/src/command_support/baseCommand.py
+++ b/cad/src/command_support/baseCommand.py
@@ -2,7 +2,8 @@
"""
baseCommand.py - base class for command objects on a command sequencer stack
-NOTE: under development, not yet used as of 080730.
+NOTE: under development, only used when USE_COMMAND_STACK is true
+(controlled by debug_pref as of before 080905)
@author: Bruce
@version: $Id$
@@ -23,21 +24,21 @@ class baseCommand(object):
"""
Abstract base class for command objects compatible with Command Sequencer.
"""
-
- #Temporary attr 'command_porting_status'. Used ONLY to keep a track of
- #commands that are ported to the new command API. the default value is
- #'None' (fully ported) and is overridden in subclasses.
- command_porting_status = None
-
-
+ __abstract_command_class = True
# default values of command subclass constants
- # WARNING: presently some of these are overridden in anyCommand and/or basicCommand;
- # that will be cleaned up after the refactoring is complete. [bruce 080815 comment]
+ # WARNING: presently some of these are overridden in anyCommand and/or
+ # basicCommand; that will be cleaned up after the refactoring is complete.
+ # [bruce 080815 comment]
+ #Temporary attr 'command_porting_status'. Used ONLY to keep a track of
+ #commands that are ported to the new command API. the default value is
+ #'None' (fully ported) and is overridden in subclasses.
+ command_porting_status = None
+
command_level = CL_ABSTRACT
- #doc
+ #doc command_level; see command_levels.py
command_parent = None # TODO: rename this to command_parentName or ... ###
# Subclasses should set this to the commandName of the parent command
diff --git a/cad/src/dna/command_support/BreakOrJoinStrands_Command.py b/cad/src/dna/command_support/BreakOrJoinStrands_Command.py
index 299d8c453..307ecd9cc 100644
--- a/cad/src/dna/command_support/BreakOrJoinStrands_Command.py
+++ b/cad/src/dna/command_support/BreakOrJoinStrands_Command.py
@@ -28,13 +28,8 @@ class BreakOrJoinStrands_Command(BuildAtoms_Command):
command_porting_status = "PARTIAL: 2008-0--05: needs PM_class refactoring"
command_level = CL_SUBCOMMAND
- # Note: maybe this should be CL_ABSTRACT so it's correct for *this* class,
- # which each subclass of this class specifying command_level = CL_SUBCOMMAND.
- # For now, this doesn't matter, since this command's name is in
- # _KLUGE_ABSTRACT_CLASSNAMES in FeatureDescriptor.py, and since
- # that code doesn't yet pay attention to CL_ABSTRACT anyway.
- # [bruce 080905 comment]
command_parent = 'BUILD_DNA'
+ __abstract_command_class = True #bruce 080905
command_can_be_suspended = False
command_should_resume_prevMode = True
diff --git a/cad/src/foundation/FeatureDescriptor.py b/cad/src/foundation/FeatureDescriptor.py
index 3cd1da6ce..494df5624 100644
--- a/cad/src/foundation/FeatureDescriptor.py
+++ b/cad/src/foundation/FeatureDescriptor.py
@@ -17,7 +17,18 @@ _KLUGE_PERMIT_INHERITED_CLASSNAMES = (
# since it doesn't have its own featurename
"Select_Command",
"selectMode",
-
+
+ # these need to be here since they still inherit from basicCommand versions
+ # where the featurename is actually defined
+ # (alternatively, we could define featurename in these classes instead
+ # of in their basicCommand superclasses, and put the basicCommand
+ # superclasses into this table; ultimately it won't matter since
+ # those class-pairs should each be merged into a single class.)
+ "SelectChunks_Command",
+ "SelectAtoms_Command",
+ "BuildAtoms_Command",
+ "Move_Command",
+
"TemporaryCommand_preMixin", # (should this count as abstract?)
"minimalCommand", # (ditto)
@@ -26,13 +37,6 @@ _KLUGE_PERMIT_INHERITED_CLASSNAMES = (
"Example_TemporaryCommand_useParentPM", # abstract, but doesn't have its own featurename
)
-_KLUGE_ABSTRACT_CLASSNAMES = (
- # todo: replace with per-class __abstract = True
- "EditCommand",
- "ExampleCommand", # (why printed twice, when not in this list?)
- "TemporaryCommand_Overdrawing",
- )
-
# == global state
_descriptor_for_feature_class = {}
@@ -55,6 +59,7 @@ _feature_class_tuple = () # tuple of feature classes, to be passed to issubclass
def short_class_name( clas):
# todo: refile into utilities.constants; has lots of inlined uses
# todo: generalize to non-class things
+ # note: used for name-mangling too, so don't change what it returns
return clas.__name__.split('.')[-1]
def canonicalize_featurename( featurename, warn = False):
@@ -159,7 +164,7 @@ def find_or_make_FeatureDescriptor( thing):
def _determine_FeatureDescriptor( thing):
"""
Determine (find or make) and return the FeatureDescriptor
- to use with thing.
+ to use with thing. (If thing is abstract, return None.)
@param thing: an object or class corresponding internally
to a specific program feature, and for which
@@ -179,9 +184,29 @@ def _determine_FeatureDescriptor( thing):
clas = thing
del thing
-
+
featurename = clas.featurename # note: not yet canonicalized
+ # See if class is declared abstract.
+ # It declares that using a name-mangled attribute, __abstract_command_class,
+ # so its subclasses don't accidentally inherit that declaration.
+ # (This is better than using command_level == CL_ABSTRACT,
+ # since that can be inherited mistakenly. REVIEW whether that
+ # attr value should survive at all.)
+ # [bruce 080905 new feature]
+
+ short_name = short_class_name( clas)
+
+ mangled_abstract_attrname = "_%s__abstract_command_class" % short_name
+ abstract = getattr(clas, mangled_abstract_attrname, False)
+ if abstract:
+ return None
+
+ if clas in _feature_class_tuple:
+ print "\n*** possible bug: %r probably ought to define __abstract_command_class = True" % short_name
+ # if not true, after review, revise this print [bruce 080905]
+ return None
+
# see if featurename is inherited
inherited_from = None # might be changed below
@@ -192,17 +217,13 @@ def _determine_FeatureDescriptor( thing):
inherited_from = base
break
- short_name = short_class_name( clas)
-
if inherited_from is not None:
# decide whether this is legitimate (use inherited description),
# or not (warn, and make up a new description).
- assert not clas in _feature_class_tuple
-
legitimate = short_name in _KLUGE_PERMIT_INHERITED_CLASSNAMES
# maybe: also add ways to register such classes,
- # and/or to mark them using __abstract = True
+ # and/or to mark them using __abstract_command_class = True
# (made unique to that class by name-mangling).
# maybe: point out in warning if it ends with Mode or Command
@@ -211,11 +232,20 @@ def _determine_FeatureDescriptor( thing):
if legitimate:
return find_or_make_FeatureDescriptor( inherited_from)
# return that even if it's None (meaning we're an abstract class)
+ # (todo: review that comment -- abstract classes are now detected earlier;
+ # can this still be None at this point? Doesn't matter for now.)
# make it unique
featurename = canonicalize_featurename( featurename, warn = True)
featurename = featurename + " " + short_name
+ print
print "developer warning: auto-extending inherited featurename to make it unique:", featurename
+ print " involved classes: %r and its subclass %r" % \
+ ( short_class_name( inherited_from),
+ short_class_name( clas) )
+ print " likely fixes: either add %r to _KLUGE_PERMIT_INHERITED_CLASSNAMES," % ( short_name, )
+ print " or define a featurename class constant for it,"
+ print " or declare it as abstract by defining __abstract_command_class = True in it."
pass # use new featurename to make a new description, below
else:
@@ -224,11 +254,6 @@ def _determine_FeatureDescriptor( thing):
assert not short_name in _KLUGE_PERMIT_INHERITED_CLASSNAMES, short_name
pass
- # see if registered as abstract class
-
- if clas in _feature_class_tuple or short_name in _KLUGE_ABSTRACT_CLASSNAMES:
- return None
-
# use featurename (perhaps modified above) to make a new description
descriptor_constructor = _choose_descriptor_constructor( clas)
diff --git a/cad/src/operations/ops_debug.py b/cad/src/operations/ops_debug.py
index 336f17ae7..b7b8da16c 100644
--- a/cad/src/operations/ops_debug.py
+++ b/cad/src/operations/ops_debug.py
@@ -52,7 +52,8 @@ def import_all_modules_cmd(glpane): #bruce 080721
modules = file1.readlines()
file1.close
os.remove(tmpfile)
-
+
+ print
print "will scan %d source files from AllPyFiles" % len(modules) # 722 files as of 080721!
modules.sort()
@@ -160,16 +161,8 @@ def export_command_table_cmd(glpane, _might_reload = True): #bruce 080721, unfin
continue
print "found %d distinct global values in %d modules" % ( len(global_values), mcount)
-
- print "found %d command_packages" % len(all_command_packages_dict) # a dict, from and to their names
- all_command_packages_list = all_command_packages_dict.values()
- all_command_packages_list.sort()
-
- # print "\n".join( all_command_packages_list)
- # print
-
if 1:
- # not needed, just curious how many types there are
+ # not really needed, just curious how many types of global values there are
global_value_types = {} # maps type -> type (I assume all types are hashable)
for v in global_values.itervalues():
t = type(v)
@@ -183,6 +176,13 @@ def export_command_table_cmd(glpane, _might_reload = True): #bruce 080721, unfin
# print global_value_types.values() # just to see it...
print
+ print "found %d command_packages" % len(all_command_packages_dict) # a dict, from and to their names
+ all_command_packages_list = all_command_packages_dict.values()
+ all_command_packages_list.sort()
+
+ # print "\n".join( all_command_packages_list)
+ # print
+
# find command descriptors in global_values
descriptors = {}
for thing in global_values.itervalues():
@@ -199,7 +199,8 @@ def export_command_table_cmd(glpane, _might_reload = True): #bruce 080721, unfin
if cp not in all_command_packages_dict:
print "bug: command package not found in initial scan:", cp
if command_packages_with_commands.has_key(cp):
- print "warning: command package with more than one command:", cp
+ # this is normal now; todo: print at most once per cp
+ print "fyi: command package with more than one command:", cp
command_packages_with_commands[ cp] = cp
for cp in all_command_packages_list:
diff --git a/cad/src/prototype/test_commands.py b/cad/src/prototype/test_commands.py
index ea54b0767..55868b8b5 100755
--- a/cad/src/prototype/test_commands.py
+++ b/cad/src/prototype/test_commands.py
@@ -107,6 +107,7 @@ class ExampleCommand(_superclass):
featurename = "Prototype: Undocumented Example Command"
from utilities.constants import CL_EDIT_GENERIC
command_level = CL_EDIT_GENERIC
+ __abstract_command_class = True
def init_gui(self):
print "init_gui in", self ###
diff --git a/cad/src/temporary_commands/TemporaryCommand.py b/cad/src/temporary_commands/TemporaryCommand.py
index a388392b7..5ce42cb69 100644
--- a/cad/src/temporary_commands/TemporaryCommand.py
+++ b/cad/src/temporary_commands/TemporaryCommand.py
@@ -120,6 +120,7 @@ class TemporaryCommand_Overdrawing( TemporaryCommand_preMixin,
and GraphicsMode.
"""
GraphicsMode_class = _TemporaryCommand_Overdrawing_GM
+ __abstract_command_class = True
featurename = "Undocumented Temporary Command"
# (I don't know if this featurename is ever user-visible;
# if it is, it's probably wrong -- consider overriding