A hierarchy python question

will generate error:

Thanks castironpi for your answer, I’ll read a little bit about what relational database can do now that I know it exists and perhaps use it if it’s not too complicated to me. In the meantime I thought about an other solution which may be painful but let me propose it and tell me what do you think about it:

main.py

import direct.directbase.DirectStart
from pandac.PandaModules import *
from direct.task.Task import Task
from direct.showbase.DirectObject import DirectObject
import sys,test

class RoomSelect(DirectObject):
   def __init__(self):
      self.accept('escape',sys.exit)

      self.t= test.Test()
      
      taskMgr.add(self.checkValueInTest, 'checkValueInTest')

   def printA(self):
       print 'A'

   def checkValueInTest(self,task):
      if self.t.checkValue== True:
         self.printA()
         taskMgr.remove('checkValueInTest')
      return Task.cont

RoomSelect()
run()

test.py

import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import *


class Test(DirectObject):
  def __init__(self):
    
    self.checkValue=False
    self.printMethod()

  def printMethod(self):
    self.checkValue=True

This works but the real case will be much more difficult to implement because there will be much more than one boolean that need to be checked each frame.
Well, tell me what do you think about it…

In main.py:

class RoomSelect(DirectObject):
   def __init__(self):
      self.accept('escape',sys.exit)

      self.t= test.Test(self) # <-- pass the "parent" class to init
      self.t.reparentTo(self)

   def printA(self):
       print 'A' 

In test.py:

class Test(DirectObject):
  def __init__(self, roomselect):
    self.roomselect = roomselect
    self.printMethod()

  def printMethod(self):
    self.roomselect.printA()

tallmystcarpet,

Short answer:

Use a relational database.

Long answer:

Bad news all around, I’m afraid. The real solution doesn’t exist as of today’s progress. You want objects A and B to participate in relation R, such that querying R for either can identify the other. In your case, R is one-to-one, but won’t always be.

Ideally, we would declare R( A, B ) just like that.

R( A, B )

Then we retrieve:

x= participant in R where parameter 1 == A
y= participant in R where parameter 2 == B

In Python, you can build a dual-mapping object, such that

Ra[ A ] = B and Rb[ B ] = A

But one is always reluctant to; he won’t want to stop short of a full relational database anyway. To build our own, we would need keywords like ‘mutable’ and ‘immutable’ in the table defs., because our best search algorithm on mutable objects is different from that on immutable ones. So we retreat to existing relational databases, and lose lots of nifty Python. However, in our case,

R = Relation( )
R( A, B )
x= R.first( A )

would be all the declaring we would need out of the class, and all your second class would need is a reference to the Relation object.

In specialized cases, one may have shortcut solutions available:

  • require test.printA to be set, then call printA
  • require test.otherClass, then call otherClass.printA statically
  • initialize test object with a reference to the RoomSelect object
  • set test object with a reference to the RoomSelect object after creation, prior to needing the printA call. This creates behavior that is a little tricky; you’ll need a default or need to catch some exceptions-- ‘printA member not set’.

will generate error:

Thanks castironpi for your answer, I’ll read a little bit about what relational database can do now that I know it exists and perhaps use it if it’s not too complicated to me. In the meantime I thought about an other solution which may be painful but let me propose it and tell me what do you think about it:

main.py

import direct.directbase.DirectStart
from pandac.PandaModules import *
from direct.task.Task import Task
from direct.showbase.DirectObject import DirectObject
import sys,test

class RoomSelect(DirectObject):
   def __init__(self):
      self.accept('escape',sys.exit)

      self.t= test.Test()
      
      taskMgr.add(self.checkValueInTest, 'checkValueInTest')

   def printA(self):
       print 'A'

   def checkValueInTest(self,task):
      if self.t.checkValue== True:
         self.printA()
         taskMgr.remove('checkValueInTest')
      return Task.cont

RoomSelect()
run()

test.py

import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import *


class Test(DirectObject):
  def __init__(self):
    
    self.checkValue=False
    self.printMethod()

  def printMethod(self):
    self.checkValue=True

This works but the real case will be much more difficult to implement because there will be much more than one boolean that need to be checked each frame.
Well, tell me what do you think about it…

This doesn’t make sense. My understanding is that teedee’s solution would be adequate in this case. I believe his meaning was to just replace the class def; you still need the imports.

Your idea is indirect. I personally favor direct, but indirect can be quite dazzling. The direct way would be, somehow a Test obtains a reference to a RoomSelect, then calls printA whenever it needs.

Indirect ways are- a Test object adds itself to a queue when it needs printing, then certain RoomSelects check the queue once a frame.

  • a Test object adds itself to a queue, then wakes a thread and blocks; the thread calls printA on a RoomSelect with the Test in the queue, then wakes its caller and blocks; then caller continues.These ways, the Tests don’t need access to the RoomSelects, but do need access to the queue and threads and synchro. objects.

You still need your import calls, I only put the parts of the code that I changed in my post.

Waouw, I re-tested teedee’s suggestion which worked like a charm :slight_smile:
I surely did something wrong the first time I tried…

A big thanks to both of you… :wink:
Now I’m feeling quiet lazy to re-write all the code I need to adapt to this new format :-s