• Welcome to Theos PowerBasic Museum 2017.

Array of Interfaces

Started by Mark Smit, August 18, 2008, 03:48:48 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Mark Smit

Hi Jose,

I hope you are reading this because I'm a little stuck.

First off thank you VERY much for everything you've done for the community. All your hard work is very much appreciated. Perhaps there is some way I could buy you a beer over PayPal or something ;)

Ok here's my issue...

1. I have a base class "CLayer"
2. I also have some other classes "CBackground", "CBorder", etc... (these INHERIT CLayer, ILayer)

How can I make an array of generic interfaces that can, at run time, be set to any one of my other classes "CBackground", "CBorder"

Here's what I would like to do in code...


#COMPILER PBCC
#COMPILE EXE
#DIM ALL

CLASS CBackground
    INSTANCE dwColor    AS DWORD
   
    INTERFACE IBackground:INHERIT CLayer, ILayer
    END INTERFACE
END CLASS


CLASS CBorder
    INSTANCE dwColor    AS DWORD
    INSTANCE dWidth     AS DOUBLE
    INSTANCE lStyle     AS LONG
   
    INTERFACE IBorder:INHERIT CLayer, ILayer
    END INTERFACE
END CLASS


CLASS CLayer
    INSTANCE szName AS STRING
   
    INTERFACE ILayer:INHERIT IUNKNOWN
    END INTERFACE
END CLASS



FUNCTION PBMAIN () AS LONG
    DIM Layer(2) AS IUNKNOWN
   
    Layer(0) = CLASS "CLayer"
    Layer(1) = CLASS "CBackground"
    Layer(2) = CLASS "CBorder"
   
   
    STDOUT"Press ANY key to continue."
    WAITKEY$
END FUNCTION



I guess this would be like using a UNION but I'm not sure how to go about doing this.

Thanks!

James C. Fuller

Forgive me for stepping in here and José can correct me if I am wrong.
There is really no Pb supported documented way to create generic cases. You do have a couple alternatives; Containment or the POKE  .AddRef method.
Containment is where you create the Class you want inside the now derived class instead of inheriting from it.

The other is detailed in my example code on PowerBASIC web site.

I'll post a couple of examples later if wanted?

James




James C. Fuller

I think this is backward of what you wanted but it may give you some ideas??

James


#COMPILER PBCC
#COMPILE EXE
#DIM ALL

CLASS cBackground
    INSTANCE dwColor AS DWORD
    INTERFACE iBackground : INHERIT IUNKNOWN
        PROPERTY GET dwColor() AS DWORD
            PROPERTY = dwColor
        END PROPERTY
        PROPERTY SET dwColor(BYVAL Param AS DWORD)
            dwColor = Param
        END PROPERTY
    END INTERFACE
END CLASS

CLASS cBorder
    INSTANCE dwColor AS DWORD
    INSTANCE dwWindth AS DOUBLE
    INSTANCE lStyle     AS LONG
    INTERFACE iBorder : INHERIT IUNKNOWN
        PROPERTY GET dwColor() AS DWORD
            PROPERTY = dwColor
        END PROPERTY
        PROPERTY SET dwColor(BYVAL Param AS DWORD)
            dwColor = Param
        END PROPERTY
    END INTERFACE
   
END CLASS
' Init in CLASS METHOD Create so don't use as a base class
CLASS cLayer
    INSTANCE szName AS STRING
    INSTANCE oBackground AS iBackGround
    INSTANCE oBorder    AS iBorder
    CLASS METHOD CREATE
        oBackground = CLASS "cBackground"
        oBorder = CLASS "cBorder"
    END METHOD
    INTERFACE iLayer : INHERIT IUNKNOWN
        PROPERTY GET Background() AS iBackground
            PROPERTY = oBackground
        END PROPERTY
        PROPERTY GET BORDER() AS iBorder
            PROPERTY = oBorder
        END PROPERTY
    END INTERFACE
END CLASS


FUNCTION PBMAIN () AS LONG
    REDIM oLayer(2) AS iLayer
    LOCAL oBorder AS iBorder
    LOCAL dwColor AS DWORD
    oLayer(0) = CLASS "cLayer"
    IF ISNOTHING(oLayer(0)) THEN
        PRINT " No oLayer(0)"
    END IF
    oLayer(1) = CLASS "cLayer"
    oLayer(2) = CLASS "cLayer"

    oLayer(0).Border.dwColor = &HC0C0C0
    dwColor = oLayer(0).Border.dwColor
   
    PRINT "dwColor = ";dwColor
    WAITKEY$
END FUNCTION


Mark Smit

Hi James,

Thanks for stepping in!

More examples are always appreciated, if you have time ;)

Here is how I was doing this before objects...


#COMPILE EXE
#DIM ALL

TYPE LAYER_BACKGROUND
   dwColor AS DWORD
END TYPE

TYPE LAYER_BORDER
   dwColor AS DWORD
   dWidth  AS DOUBLE
   lStyle  AS LONG
END TYPE

UNION LAYER_UNION
   mBackground AS LAYER_BACKGROUND
   mBorder     AS LAYER_BORDER
END UNION

TYPE LAYER
   szName  AS ASCIIZ * 256
   lType   AS LONG         '0 = Undefined, 1 = Background, 2 = Border
   LAYER_UNION
END TYPE


FUNCTION PBMAIN () AS LONG
   DIM Layer(1) AS LAYER
   
   Layer(0).szName = "Background"
   Layer(0).lType  = 1
   Layer(0).mBackground.dwColor = RGB(255, 255, 255)
   
   Layer(1).szName = "Border"
   Layer(1).lType  = 2
   Layer(1).mBorder.dwColor = RGB(255, 255, 255)
   Layer(1).mBorder.dWidth = 1
   Layer(1).mBorder.lStyle = 0
END FUNCTION




Mark Smit

Hey James,

So if I understand correctly, what you have done there is a compound object reference?

1. I make a base layer class
2. Inside the base class I have variables/instances for each layer type (background, border, etc...)
3. Use compound object reference to get to each layer type



James C. Fuller

Yes you understand correctly but I'm not sure this is a good candidate for an object?
I haven't had a chance to look at your last code closely.

James

Mark Smit

Hey James,

Well the code I posted wasn't the full "Object". The entire project I think will benefit from objects.

The software I've been writing is a CAD package for geologists.

The same drawing engine is used in multiple places/programs.

Well.Canvas.OpenGL
Well.Canvas.DirectX
Well.Canvas.PDF
Well.Canvas.GDI
Well.Chart(Index).Track(Index).Layer(Index)
Well.DataSource.Cache
Well.DataSource
Well.SecureData

These objects seem to be a great way to write it all once and reuse them for the CAD, Server and Viewer software.

James C. Fuller

This is the way I would attack  it with the code you posted:

James


#COMPILER PBCC
#COMPILE EXE
#DIM ALL
%LAYERBACKGROUND = 1
%LAYERBORDER = 2
%LAYERERROR = -1

CLASS cLayer
    INSTANCE sName AS STRING
    INSTANCE dwColor AS DWORD
    INSTANCE dWidth AS DOUBLE
    INSTANCE lType,lStyle AS LONG
    INTERFACE iLayer : INHERIT IUNKNOWN
   
        PROPERTY GET TYPE() AS LONG
            PROPERTY = lType
        END PROPERTY
        PROPERTY SET TYPE(BYVAL Param AS LONG)
            lType = Param
        END PROPERTY

        PROPERTY GET COLOR() AS DWORD
            PROPERTY = dwColor
        END PROPERTY
        PROPERTY SET COLOR(BYVAL Param AS DWORD)
            dwColor = Param
        END PROPERTY
       
        PROPERTY GET WIDTH() AS DOUBLE
            IF lType = %LAYERBORDER THEN
                PROPERTY = dWidth
            ELSE
                PROPERTY = %LAYERERROR
            END IF
        END PROPERTY
        PROPERTY SET WIDTH(BYVAL Param AS DOUBLE)
            dWidth = Param
        END PROPERTY
       
        PROPERTY GET STYLE() AS LONG
            IF lType = %LAYERBORDER THEN
               PROPERTY = lStyle
            ELSE
                PROPERTY = %LAYERERROR
            END IF
        END PROPERTY
        PROPERTY SET STYLE(BYVAL Param AS LONG)
            lStyle = Param
        END PROPERTY
       
        PROPERTY GET NAME() AS STRING
            PROPERTY = sName
        END PROPERTY
        PROPERTY SET NAME(BYVAL Param AS STRING)
            sName = Param
        END PROPERTY
       
    END INTERFACE
END CLASS


FUNCTION PBMAIN () AS LONG
    REDIM oLayer(2) AS iLayer
    LOCAL dwColor AS DWORD
    LOCAL dWidth AS DOUBLE
    oLayer(0) = CLASS "cLayer"
    IF ISNOTHING(oLayer(0)) THEN
        PRINT " No oLayer(0)"
    END IF
    oLayer(1) = CLASS "cLayer"
    IF ISNOTHING(oLayer(1)) THEN
        PRINT " No oLayer(1)"
    END IF
   
    oLayer(0).NAME = "Background"
    oLayer(0).TYPE  = 1
    oLayer(0).COLOR = RGB(255, 255, 255)

    oLayer(1).NAME = "Border"
    oLayer(1).TYPE  = 2
    oLayer(1).COLOR = RGB(255, 255, 255)
    oLayer(1).WIDTH = 1
    oLayer(1).STYLE = 0
    dwColor =  oLayer(1).COLOR
    ?"DwColor = ";dwColor
    dWidth = oLayer(0).WIDTH
    IF dWidth = %LAYERERROR THEN
        ? "Not A Border Layer"
    ELSE
        ?"Border Width = ";dWidth
    END IF
   
    dWidth = oLayer(1).WIDTH
    IF dWidth = %LAYERERROR THEN
        ? "Not A Border Layer"
    ELSE
        ?"Border Width = ";dWidth
    END IF
   
    WAITKEY$
END FUNCTION

José Roca

 
Quote
Forgive me for stepping in here and José can correct me if I am wrong.

Don't be afraid in stepping in. I have expertise in COM programming, but OOP is new to me. We have got the same compiler, but we are using it for different purposes.