问:
Navigating through different controllers in appcelerator
I want to navigate from DashboardController to VideoPlayerController on itemclick event of the list items in appcelerator.
But it is throwing me an error saying cannot find $.win2 (which is also the view used in DashboardController).

This is the code for DashboardController.js

```<code>var args = $.args;

var sections = [];
//JSON to populate the listview
var videoInfo = [{
    pic : "/Images/playButton.png",
    info : "This in the the title for the first video.",
    date : "03/07/2017",
    url : "https://youtu.be/zkOSR0ZRb9khttps://youtu.be/zkOSR0ZRb9k"
}, {
    pic : "/Images/playButton.png",
    info : "This in the the title for the second video.",
    date : "03/07/2017",
    url : "https://youtu.be/zkOSR0ZRb9khttps://youtu.be/zkOSR0ZRb9k"
}, {
    pic : "/Images/playButton.png",
    info : "This in the the title for the third video.",
    date : "03/07/2017",
    url : "https://youtu.be/zkOSR0ZRb9khttps://youtu.be/zkOSR0ZRb9k"
}];

function populateListView() {
    Ti.API.trace("[DashboardController.js  >>  populateListView() >>]");
    if (!_.isEmpty(videoInfo)) {
        for (var i = 0; i < videoInfo.length; i++) {
            var item = {
                template : "videoTemplate",
                iconId : {
                    image : videoInfo[i].pic
                },
                titleId : {
                    text : videoInfo[i].info
                },
                dateId : {
                    text : videoInfo[i].date
                },
                urlId : {
                    text : videoInfo[i].url
                },
                properties : {
                    backgroundColor : "transparent"
                }
            };
            sections.push(item);
        }
       $.listSection.setItems(sections);
    }
}
populateListView();
$.lView.addEventListener('itemclick',function(e){
    Ti.API.trace("[DashboardController.js  >>  Function to open VideoPlayerController >>]");
    var dataItem = videoInfo[e.itemIndex];//$.listSection.getItemAt(e.itemIndex) ;
    Ti.API.trace("Data Item is : ",dataItem);
    var videoController = Alloy.createController('VideoPlayerController',{
    "url":dataItem.url,
    "title":dataItem.info,
    "date":dataItem.date
    }).getView();
    $win2.add(videoController);
    //videoController.open();
});
</code>```

This is the code for DashboardController.xml

```<code><Alloy>
    <View id="win2" class="container">
        <View id = "v1" class ="view1"  layout ="horizontal" >
            <Button class="btnBack" ></Button>
            <Label  class = "label1">LIST VIEW EXAMPLE</Label>
        </View>
        <View class="view2">
            <SearchBar class="searchBar"></SearchBar>
        </View>
        <ListView id = "lView" class = "list1" >
             <Templates>
                    <ItemTemplate name="videoTemplate">
                        <View class = "viewTemplate" layout = "horizontal" >
                            <ImageView bindId="iconId"  id="pic"  />
                            <View class = "viewTitle" layout = "vertical" >
                                <Label bindId="titleId" id="info" />
                                <View class="viewDtUrl" layout="horizontal" >
                                    <Label bindId="dateId" id="date" />
                                    <Label bindId="urlId" id ="url" />
                                </View>
                            </View>
                        </View>
                    </ItemTemplate>
            </Templates>
            <ListSection id = "listSection">
            </ListSection>
        </ListView>
    </View>
</Alloy>
</code>```

This is the code for VidePlayerController.xml

```<code><VideoPlayer class = "video"></VideoPlayer>
        <View class="videoInfoView" layout="vertical" backgroundColor="blue">
            <Label class="titleInfo"></Label>
            <View class = "infoLabel" layout="horizontal" backgroundColor="yellow">
                <Label class="dateInfo"></Label>
                <Label class="urlInfo"></Label>
            </View>>
        </View>
</code>```

答: I think you are missing  tag in VidePlayerController.xml and also add VideoPlayer tag inside View tag in VidePlayerController.</p>

Body:
I want to navigate from DashboardController to VideoPlayerController on itemclick event of the list items in appcelerator.
But it is throwing me an error saying cannot find $.win2 (which is also the view used in DashboardController).

This is the code for DashboardController.js

var args = $.args;

var sections = [];
//JSON to populate the listview
var videoInfo = [{
    pic : "/Images/playButton.png",
    info : "This in the the title for the first video.",
    date : "03/07/2017",
    url : "https://youtu.be/zkOSR0ZRb9khttps://youtu.be/zkOSR0ZRb9k"
}, {
    pic : "/Images/playButton.png",
    info : "This in the the title for the second video.",
    date : "03/07/2017",
    url : "https://youtu.be/zkOSR0ZRb9khttps://youtu.be/zkOSR0ZRb9k"
}, {
    pic : "/Images/playButton.png",
    info : "This in the the title for the third video.",
    date : "03/07/2017",
    url : "https://youtu.be/zkOSR0ZRb9khttps://youtu.be/zkOSR0ZRb9k"
}];

function populateListView() {
    Ti.API.trace("[DashboardController.js  >>  populateListView() >>]");
    if (!_.isEmpty(videoInfo)) {
        for (var i = 0; i < videoInfo.length; i++) {
            var item = {
                template : "videoTemplate",
                iconId : {
                    image : videoInfo[i].pic
                },
                titleId : {
                    text : videoInfo[i].info
                },
                dateId : {
                    text : videoInfo[i].date
                },
                urlId : {
                    text : videoInfo[i].url
                },
                properties : {
                    backgroundColor : "transparent"
                }
            };
            sections.push(item);
        }
       $.listSection.setItems(sections);
    }
}
populateListView();
$.lView.addEventListener('itemclick',function(e){
    Ti.API.trace("[DashboardController.js  >>  Function to open VideoPlayerController >>]");
    var dataItem = videoInfo[e.itemIndex];//$.listSection.getItemAt(e.itemIndex) ;
    Ti.API.trace("Data Item is : ",dataItem);
    var videoController = Alloy.createController('VideoPlayerController',{
    "url":dataItem.url,
    "title":dataItem.info,
    "date":dataItem.date
    }).getView();
    $win2.add(videoController);
    //videoController.open();
});

This is the code for DashboardController.xml

<Alloy>
    <View id="win2" class="container">
        <View id = "v1" class ="view1"  layout ="horizontal" >
            <Button class="btnBack" ></Button>
            LIST VIEW EXAMPLE
        </View>
        <View class="view2">
            <SearchBar class="searchBar"></SearchBar>
        </View>
        <ListView id = "lView" class = "list1" >
             <Templates>
                    <ItemTemplate name="videoTemplate">
                        <View class = "viewTemplate" layout = "horizontal" >
                            <ImageView bindId="iconId"  id="pic"  />
                            <View class = "viewTitle" layout = "vertical" >

                                <View class="viewDtUrl" layout="horizontal" >

                                </View>
                            </View>
                        </View>
                    </ItemTemplate>
            </Templates>
            <ListSection id = "listSection">
            </ListSection>
        </ListView>
    </View>
</Alloy>

This is the code for VidePlayerController.xml

<VideoPlayer class = "video"></VideoPlayer>
        <View class="videoInfoView" layout="vertical" backgroundColor="blue">

            <View class = "infoLabel" layout="horizontal" backgroundColor="yellow">

            </View>>
        </View>


来源: stackexchange

问:
does tf slim fine tuning require gpu?
Actually I am trying to fine tune inceptionV3 model using tf slim fine tuning example on git hub it is giving me this error :

InvalidArgumentError (see above for traceback): Cannot assign a device to node 'InceptionV3/AuxLogits/Conv2d_2b_1x1/biases/RMSProp_1': Could not satisfy explicit device specification '/device:GPU:0' because no devices matching that specification are registered in this process; available devices: /job:localhost/replica:0/task:0/cpu:0

Colocation Debug Info:

Colocation group had the following types and devices:

ApplyRMSProp: CPU

Const: CPU

Assign: CPU

IsVariableInitialized: CPU

Identity: CPU

VariableV2: CPU

     [[Node: InceptionV3/AuxLogits/Conv2d_2b_1x1/biases/RMSProp_1 = VariableV2_class=["loc:@InceptionV3/AuxLogits/Conv2d_2b_1x1/biases"], container="", dtype=DT_FLOAT, shape=[5], shared_name="", _device="/device:GPU:0"]]

答: Please provide more information about your Tensorflow installation (GPU or CPU installation). If you are running a GPU Tensorflow version this probably is raising the error.</p>

ContentLicense: CC BY-SA 3.0

Title: does tf slim fine tuning require gpu?


问:
Using and controlling Spring transactions within Struts 2 actions
I have been working for a while on a project with the following components:

Struts2.1.8.1,

Spring 3.0.3

JPA 2.0,

Hibernate 3

I am using Spring's EntityManager magic... But I'm having problems dealing with transactions inside my actions. For instance, I am setting values on my persisted object in several methods within my class, and I want to be able to rollback if the validate method finds a validation error, or commit these changes otherwise. I have already spent quite a long time reading half of the internet for a comprehensive explanation. Unfortunately, no complete examples exist (at least similar to my stack).

I have stumbled with this thread on a mailing list: @Transactional Spring Annotation in a Struts2 Action does not work. The message I'm linking at seems to have a pretty simple and straightforward solution, using a TransactionInterceptor will do the trick it seems... The problem is that I'm not finding useful information regarding this interceptor.

Anyone here has experience with this technology and can spare a tip and a link or two on how to use Spring transactions inside Struts2 actions?

Thanks!

- Edit 1 -

I have set up a test project if you are interested, just download the file and try it out (or inspect it). Thanks!

答:
Based on your question, here's what I understand about your problem.

You want to wrap your action invocation in a transaction. If the validate method records validation errors, you want to roll the transaction back. Presumably, you also want to rollback in case of an error.

Solution

Create an interceptor that will:

Start a transaction

Invoke the action inside of a try/catch block

Rollback the transaction if there is an exception or if there are any validation errors on the action (this can be detected using action.hasErrors)

Commit the transaction

You will probably want this interceptor defined pretty early in the stack. I don't know of any pre-built interceptors for this (although there may be some), but it should be fairly easy to assemble.

Update

I don't use Spring, so I can't say how the JPA transaction support works there, but you can handle transactions for your EntityManager like:

```<code>try {
    entityManager.getTransaction().begin();
    // do your thing
    entityManager.getTransaction().commit();
} catch (Exception e) {
    entityManager.getTransaction().rollback();
    throw new PersistenceException(e);
}
</code>```

This is just a crude example, but it should illustrate the point.

ContentLicense: CC BY-SA 4.0

Body:
Based on your question, here's what I understand about your problem.

You want to wrap your action invocation in a transaction. If the validate method records validation errors, you want to roll the transaction back. Presumably, you also want to rollback in case of an error.

Solution

Create an interceptor that will:

Start a transaction

Invoke the action inside of a try/catch block

Rollback the transaction if there is an exception or if there are any validation errors on the action (this can be detected using action.hasErrors)

Commit the transaction

You will probably want this interceptor defined pretty early in the stack. I don't know of any pre-built interceptors for this (although there may be some), but it should be fairly easy to assemble.

Update

I don't use Spring, so I can't say how the JPA transaction support works there, but you can handle transactions for your EntityManager like:

try {
    entityManager.getTransaction().begin();
    // do your thing
    entityManager.getTransaction().commit();
} catch (Exception e) {
    entityManager.getTransaction().rollback();
    throw new PersistenceException(e);
}

This is just a crude example, but it should illustrate the point.

ContentLicense: CC BY-SA 2.5


问:
Carousel type of slide between two divs
I am trying to have two div cards showing in a carousel manner. A user is presented with a card with a graph view with. The card also has a button for more info; when he clicks in the info button the card should slide to the right of the screen and disappear, while a card containing the supporting info should shows from the left of the screen.

sorry for the lack of knowledge in advance

here's is what I have written.

HTML:

```<code>            <div id="userNav" class="box -width--4of4">
                <div class="data-card">
                    <button id="loginPanel" class="button -fill--transparent -is--icon pull-right"><i class="fa fa-info-circle"></i></button>
                  <div id="container" style="min-width: 310px; height: 400px; margin: 20px auto"></div>
                </div>
            </div>
</code>```

JQuery:

```<code> $('#loginPanel').click(function(){

            if ($('#userNav').is(':hidden')) {

               $('#userNav').show('slide',{direction:'left'},1000);
            } else {

               $('#userNav').hide('slide',{direction:'left'},1000);
            }
});

$('#loginPanel1').click(function(){

            if ($('#userNav').is(':hidden')) {

               $('#userNav').show('slide',{direction:'right'},1000);
            } else {

               $('#userNav').hide('slide',{direction:'right'},1000);
            }
});
</code>```

答:
You could wrap the two cards in a container, set it to position: relative; and make the cards absolutely positioned. Then you could create specific classes for the cards to simulate animation, changing position and opacity of each element simultaneously over a set duration.

This can be achieved in several different ways, but here is a fiddle showing the basic concept.

EDIT: Fiddle updated to reflect commented concerns.

Title: Carousel type of slide between two divs

Body:
I am trying to have two div cards showing in a carousel manner. A user is presented with a card with a graph view with. The card also has a button for more info; when he clicks in the info button the card should slide to the right of the screen and disappear, while a card containing the supporting info should shows from the left of the screen.

sorry for the lack of knowledge in advance

here's is what I have written.

HTML:

                    <button id="loginPanel" class="button -fill--transparent -is--icon pull-right"></button>

JQuery:

 $('#loginPanel').click(function(){

            if ($('#userNav').is(':hidden')) {

               $('#userNav').show('slide',{direction:'left'},1000);
            } else {

               $('#userNav').hide('slide',{direction:'left'},1000);
            }
});

$('#loginPanel1').click(function(){

            if ($('#userNav').is(':hidden')) {

               $('#userNav').show('slide',{direction:'right'},1000);
            } else {

               $('#userNav').hide('slide',{direction:'right'},1000);
            }
});


问:
Swap bootstrap text class for a google material icons
OK to preface I am new to javascript so this may not be the optimal way of doing this...

I am trying to change the color of a material icon when it is clicked. basically I am trying to turn it on and off. The problem is my code while it does find the icon does not read the class...I have tried adding a class, using an id, even a name and it fails to read it. I have see other responses where images are swapped and have tried with the image swap but I just want the color to change.

JAVASCRIPT:

```<code>function updateFavorites()
{
if($(this).find($("#staricon")).hasClass('text-warning'))
{
 $(this).find($("#staricon")).addClass('text-warning');

}
else
{
$(this).find($("#staricon")).removeClass('text-warning');
}
}
</code>```

HTML:

```<code><a  class=" stats pull-right " href="javacript:void" ><span
onclick="updateFavorites()"><i id="staricon" class="text-warning material-
icons " title="Favorite" >star</i></span></a>
</code>```

答:
Below is a code which will add class to #staricon whenever you click on it, and it will check if it already has that class. In CSS, you can define the color for that class.

Of course, you can add class or remove class or do other actions. Hope this code helps you.

$(".stats").on('click', function() {
  if (!$(this).find("#staricon").hasClass('SOME_CLASS'))
    $(this).find("#staricon").addClass('SOME_CLASS');
})```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.SOME_CLASS {
  color: green;
}</code>```

star```

Body:
OK to preface I am new to javascript so this may not be the optimal way of doing this...

I am trying to change the color of a material icon when it is clicked. basically I am trying to turn it on and off. The problem is my code while it does find the icon does not read the class...I have tried adding a class, using an id, even a name and it fails to read it. I have see other responses where images are swapped and have tried with the image swap but I just want the color to change.

JAVASCRIPT:

function updateFavorites()
{
if($(this).find($("#staricon")).hasClass('text-warning'))
{
 $(this).find($("#staricon")).addClass('text-warning');

}
else
{
$(this).find($("#staricon")).removeClass('text-warning');
}
}

HTML:

star

Body:
Below is a code which will add class to #staricon whenever you click on it, and it will check if it already has that class. In CSS, you can define the color for that class.

Of course, you can add class or remove class or do other actions. Hope this code helps you.

$(".stats").on('click', function() {
  if (!$(this).find("#staricon").hasClass('SOME_CLASS'))
    $(this).find("#staricon").addClass('SOME_CLASS');
})

.SOME_CLASS {
  color: green;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class=" stats pull-right " href="javacript:void"><span><i id="staricon" class="text-warning material-
    icons " title="Favorite" >star</i></span></a>


问:
How to remove all non-uppercase characters in a string?
Yeah I'm basically just trying to explode a phrase like Social Inc. or David Jason to SI and DJ. I've tried using explode but couldn't figure out how to explode everything BUT the capital letters, do I need to use preg_match()?

答:
Nicholas and Bernhard have provided successful regex patterns but they are not as efficient as they could be.

Use /[^A-Z]+/ and an empty replacement string with preg_replace().

```<code>preg_replace('~[^A-Z]+~', '', $string)
</code>```

The negated character class has a one or more quantifier, so longer substrings are matched and fewer replacements are required.

The multibyte/unicode equivalent would be: (Demo)

```<code>preg_replace('~[^\p{Lu}]+~u', '', 'Az+0ǻÉé')  // outputs: AÉ
</code>```

This is the best pattern to use with preg_split as well, but preg_split generates an array, so there is the extra step of calling implode.

Body:
Nicholas and Bernhard have provided successful regex patterns but they are not as efficient as they could be.

Use /[^A-Z]+/ and an empty replacement string with preg_replace().

preg_replace('~[^A-Z]+~', '', $string)

The negated character class has a one or more quantifier, so longer substrings are matched and fewer replacements are required.

The multibyte/unicode equivalent would be: (Demo)

preg_replace('~[^\p{Lu}]+~u', '', 'Az+0ǻÉé')  // outputs: AÉ

This is the best pattern to use with preg_split as well, but preg_split generates an array, so there is the extra step of calling implode.


问:
Conditional formatting: highlighting rows based on condition
Suppose I have the following table:

```<code>Date       Value
5/27/2017  5
6/10/2017  7
6/24/2017  8
7/8/2017   5
7/22/2017  10
</code>```

I want to highlight the most recent row, meaning the row with the date closest to today. I know I need to use Excel's conditional formatting capability, so I created the indicator column _inRange, which derives from this function:

```<code>=IF(AND(A2 <= TODAY()), TODAY() < A3), 1, 0)
</code>```

The new table:

Date       Value    _inRange
5/27/2017  5        0
6/10/2017  7        0
6/24/2017  8        1
7/8/2017   5        0
7/22/2017  10       0

So, where _inRange equals 1, the row should be highlighted. I can highlight the _inRange cell properly, but am having difficulties highlighting the entire row. Can anyone provide direction here? I looked at this Exceljet post but obviously was left with questions.

Edit:

I changed _inRange to boolean (I don't think boolean TRUE/FALSE versus 1-0 is the main issue, though) and am still having issues:

```<code>Date    Value   _inRange
5/27/2017   5   FALSE
6/10/2017   7   FALSE
6/24/2017   8   TRUE
7/8/2017    5   FALSE
7/22/2017   10  FALSE
</code>```

Here's a picture of my conditional formatting window:

I first select the entire table, then go to Home > Conditional Formatting > Highlight Cells Rules > Equal To and set the value as TRUE. Then I change the column as E. Trauger suggested but nothing changes.

答:
The way I would do this would be to use the conditional formatting on the entire row, where for any cell in that row, it is going to check the _inRange of that row. Something like this, after New Formatting Rule --> Use a Formula to Determine which cells to format:

```<code>=INDEX(C:C,ROW())=1
</code>```

Replace C:C with whatever column _inRange is in, and apply the formatting to the entire table.

Body:
Suppose I have the following table:

Date       Value
5/27/2017  5
6/10/2017  7
6/24/2017  8
7/8/2017   5
7/22/2017  10

I want to highlight the most recent row, meaning the row with the date closest to today. I know I need to use Excel's conditional formatting capability, so I created the indicator column _inRange, which derives from this function:

=IF(AND(A2 <= TODAY()), TODAY() < A3), 1, 0)

The new table:

Date       Value    _inRange
5/27/2017  5        0
6/10/2017  7        0
6/24/2017  8        1
7/8/2017   5        0
7/22/2017  10       0

So, where _inRange equals 1, the row should be highlighted. I can highlight the _inRange cell properly, but am having difficulties highlighting the entire row. Can anyone provide direction here? I looked at this Exceljet post but obviously was left with questions.

Edit:

I changed _inRange to boolean (I don't think boolean TRUE/FALSE versus 1-0 is the main issue, though) and am still having issues:

Date    Value   _inRange
5/27/2017   5   FALSE
6/10/2017   7   FALSE
6/24/2017   8   TRUE
7/8/2017    5   FALSE
7/22/2017   10  FALSE

Here's a picture of my conditional formatting window:

I first select the entire table, then go to Home > Conditional Formatting > Highlight Cells Rules > Equal To and set the value as TRUE. Then I change the column as E. Trauger suggested but nothing changes.

Body:
The way I would do this would be to use the conditional formatting on the entire row, where for any cell in that row, it is going to check the _inRange of that row. Something like this, after New Formatting Rule --> Use a Formula to Determine which cells to format:

=INDEX(C:C,ROW())=1

Replace C:C with whatever column _inRange is in, and apply the formatting to the entire table.


问:
How to perform a simple update using Subsonic ,in Visual STudio(c#)
I have a very simple update.According to the ID of the table,I want to set a boolean column to true.The problem is that I my knowledge to subsonic is like 'pitch black'.

I have done the following but it does not work.

```<code>new SubSonic.Update(FundReturn.Schema).Set(FundReturn.Columns.IsDeleted).EqualTo(1)
          .Where(FundReturn.Columns.FundId).IsEqualTo(Convert.ToInt32(row.RecordID)).Execute();
</code>```

The above line seems very logical,however it does not work.

I would appreciate any help given

答:
Woah there....  it's a lot simpler that you might be thinking....</p>

```<code>var objActiveRecord = SomeActiveRecordType.SingleOrDefault(o => o.Id == iId);
objActiveRecord.SomeBoolProperty = true;
objActiveRecord.Update();
</code>```

Body:
I have a very simple update.According to the ID of the table,I want to set a boolean column to true.The problem is that I my knowledge to subsonic is like 'pitch black'.

I have done the following but it does not work.

new SubSonic.Update(FundReturn.Schema).Set(FundReturn.Columns.IsDeleted).EqualTo(1)
          .Where(FundReturn.Columns.FundId).IsEqualTo(Convert.ToInt32(row.RecordID)).Execute();

The above line seems very logical,however it does not work.

I would appreciate any help given

Body:
Woah there....  it's a lot simpler that you might be thinking....

var objActiveRecord = SomeActiveRecordType.SingleOrDefault(o => o.Id == iId);
objActiveRecord.SomeBoolProperty = true;
objActiveRecord.Update();


问:
How to richly style AOR Edit page
Have to create an edit Page editing a number of parameters on an instance of a'tale' resource.

However adding any element such as an MUI Card or even a div, is causing the app to freeze in various ways.

These are the approaches I have tried.

1) Adding a card component or placing my elements within a div for styling

```<code>export const EditorEditTale = (props) => {
  return (
  <Edit {...props} title="Tale Editor">
    <SimpleForm >
      <div>
        <Image />
        <TaleCardHeader props={ props } style={taleCardHeaderStyle.editor} />
      </div>
    </SimpleForm>
  </Edit>
  )
};
</code>```

This is causing nothing to render.

Second approach, assuming that the record and basePath arent getting propagated to the children completely. Trying to use component like below.

```<code>const Input = ({record, basePath}) => {
  return (
    <div>
      <LongTextInput source="taleText" />
    </div>
  )
}
</code>```

This is causing the page to not render with everything in some kind of locking loop with the error - cannot read property touched of undefined.

How should I create a custom Edit page with a complex inputs and styling.

UPDATE: Been trying to write a custom form to substitute the SimpleForm component with no luck so far.

答:
To create a custom form you can follow these steps:

make an exact copy of SimpleForm to your project.

rename SimpleForm to what you want.

fix all the relative imports.

test the new form until it works.

I made a minimum working form based on current master branch's SimpleForm

```<code>import React, { Children, Component } from 'react';
import PropTypes from 'prop-types';
import { reduxForm, Field } from 'redux-form';
import { connect } from 'react-redux';
import compose from 'recompose/compose';
import getDefaultValues from 'admin-on-rest/mui/form/getDefaultValues';
import FormField from 'admin-on-rest/mui/form/FormField';
import Toolbar from 'admin-on-rest/mui/form/Toolbar';

const formStyle = { padding: '0 1em 1em 1em' };

export class PostForm extends Component {
    handleSubmitWithRedirect = (redirect = this.props.redirect) => this.props.handleSubmit(values => this.props.save(values, redirect));

    render() {
        const { children, invalid, record, resource, basePath, submitOnEnter, toolbar } = this.props;
        return (
            <form className="simple-form">
                <Field name="name_of_a_field" component="input" />
                {toolbar && React.cloneElement(toolbar, {
                    handleSubmitWithRedirect: this.handleSubmitWithRedirect,
                    invalid,
                    submitOnEnter,
                })}
            </form>
        );
    }
}

PostForm.propTypes = {
    basePath: PropTypes.string,
    children: PropTypes.node,
    defaultValue: PropTypes.oneOfType([
        PropTypes.object,
        PropTypes.func,
    ]),
    handleSubmit: PropTypes.func, // passed by redux-form
    invalid: PropTypes.bool,
    record: PropTypes.object,
    resource: PropTypes.string,
    redirect: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.bool,
    ]),
    save: PropTypes.func, // the handler defined in the parent, which triggers the REST submission
    submitOnEnter: PropTypes.bool,
    toolbar: PropTypes.element,
    validate: PropTypes.func,
};

PostForm.defaultProps = {
    submitOnEnter: true,
    toolbar: <Toolbar />,
};

const enhance = compose(
    connect((state, props) => ({
        initialValues: getDefaultValues(state, props),
    })),
    reduxForm({
        form: 'record-form',
        enableReinitialize: true,
    }),
);

export default enhance(PostForm);
</code>```

The above code works for AOR's example.

I hope this helps.

(import might be slightly different when you have AOR as npm dependency :

```<code>import getDefaultValues from 'admin-on-rest/lib/mui/form/getDefaultValues';
import FormField from 'admin-on-rest/lib/mui/form/FormField';
import Toolbar from 'admin-on-rest/lib/mui/form/Toolbar';
</code>```

)

Title: How to richly style AOR Edit page

Body:
Have to create an edit Page editing a number of parameters on an instance of a'tale' resource.

However adding any element such as an MUI Card or even a div, is causing the app to freeze in various ways.

These are the approaches I have tried.

1) Adding a card component or placing my elements within a div for styling

export const EditorEditTale = (props) => {
  return (
  <Edit {...props} title="Tale Editor">
    <SimpleForm >

        <Image />
        <TaleCardHeader props={ props } style={taleCardHeaderStyle.editor} />

    </SimpleForm>
  </Edit>
  )
};

This is causing nothing to render.

Second approach, assuming that the record and basePath arent getting propagated to the children completely. Trying to use component like below.

const Input = ({record, basePath}) => {
  return (

      <LongTextInput source="taleText" />

  )
}

This is causing the page to not render with everything in some kind of locking loop with the error - cannot read property touched of undefined.

How should I create a custom Edit page with a complex inputs and styling.

UPDATE: Been trying to write a custom form to substitute the SimpleForm component with no luck so far.

Body:
To create a custom form you can follow these steps:

make an exact copy of SimpleForm to your project.

rename SimpleForm to what you want.

fix all the relative imports.

test the new form until it works.

I made a minimum working form based on current master branch's SimpleForm

import React, { Children, Component } from 'react';
import PropTypes from 'prop-types';
import { reduxForm, Field } from 'redux-form';
import { connect } from 'react-redux';
import compose from 'recompose/compose';
import getDefaultValues from 'admin-on-rest/mui/form/getDefaultValues';
import FormField from 'admin-on-rest/mui/form/FormField';
import Toolbar from 'admin-on-rest/mui/form/Toolbar';

const formStyle = { padding: '0 1em 1em 1em' };

export class PostForm extends Component {
    handleSubmitWithRedirect = (redirect = this.props.redirect) => this.props.handleSubmit(values => this.props.save(values, redirect));

    render() {
        const { children, invalid, record, resource, basePath, submitOnEnter, toolbar } = this.props;
        return (
            <form className="simple-form">
                <Field name="name_of_a_field" component="input" />
                {toolbar && React.cloneElement(toolbar, {
                    handleSubmitWithRedirect: this.handleSubmitWithRedirect,
                    invalid,
                    submitOnEnter,
                })}
            </form>
        );
    }
}

PostForm.propTypes = {
    basePath: PropTypes.string,
    children: PropTypes.node,
    defaultValue: PropTypes.oneOfType([
        PropTypes.object,
        PropTypes.func,
    ]),
    handleSubmit: PropTypes.func, // passed by redux-form
    invalid: PropTypes.bool,
    record: PropTypes.object,
    resource: PropTypes.string,
    redirect: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.bool,
    ]),
    save: PropTypes.func, // the handler defined in the parent, which triggers the REST submission
    submitOnEnter: PropTypes.bool,
    toolbar: PropTypes.element,
    validate: PropTypes.func,
};

PostForm.defaultProps = {
    submitOnEnter: true,
    toolbar: <Toolbar />,
};

const enhance = compose(
    connect((state, props) => ({
        initialValues: getDefaultValues(state, props),
    })),
    reduxForm({
        form: 'record-form',
        enableReinitialize: true,
    }),
);

export default enhance(PostForm);

The above code works for AOR's example.

I hope this helps.

(import might be slightly different when you have AOR as npm dependency :

import getDefaultValues from 'admin-on-rest/lib/mui/form/getDefaultValues';
import FormField from 'admin-on-rest/lib/mui/form/FormField';
import Toolbar from 'admin-on-rest/lib/mui/form/Toolbar';

)


问:
Stored procedure for multiple ouput
Say I have a table USER exactly like below:

```<code> User    |   Password   |   Last_Update       |  Access
 --------+--------------+---------------------+-------------
 John        Gjh56fs        July 1st, 2017       Admin
 Mike        5hD75AR        June 21st, 2017      Read Only
</code>```

This table will always have these two records and only password and last update will change occasionally. An external process needs the User and Pass of both users via a stored procedure call.

What is the best way to do this? Can we do a stored procedure to return both user's and passwords? Do we need to make 2 for both records? Do I need to make 4 for each user/pass individually? I guess I am wondering if a stored procedure can handle multiple output because I never personally did this.

This is for an Oracle database.

答:
I think you are just confused with stored scalar function and stored procedure. A stored procedure can return scalar value, a table result set as well as multiple result sets. With that below sample is a valid stored procedure

```<code>create procedure mysp
as
begin
select * from tbl1;
select * from tbl2;
end
</code>```

Finally, a piece of suggestion don't store password as plain text in database.

Title: Stored procedure for multiple ouput

Body:
Say I have a table USER exactly like below:

 User    |   Password   |   Last_Update       |  Access
 --------+--------------+---------------------+-------------
 John        Gjh56fs        July 1st, 2017       Admin
 Mike        5hD75AR        June 21st, 2017      Read Only

This table will always have these two records and only password and last update will change occasionally. An external process needs the User and Pass of both users via a stored procedure call.

What is the best way to do this? Can we do a stored procedure to return both user's and passwords? Do we need to make 2 for both records? Do I need to make 4 for each user/pass individually? I guess I am wondering if a stored procedure can handle multiple output because I never personally did this.

This is for an Oracle database.

Body:
I think you are just confused with stored scalar function and stored procedure. A stored procedure can return scalar value, a table result set as well as multiple result sets. With that below sample is a valid stored procedure

create procedure mysp
as
begin
select * from tbl1;
select * from tbl2;
end

Finally, a piece of suggestion don't store password as plain text in database.


问:
Programmatically binding List to ListBox
Let's say, for instance, I have the following extremely simple window:

```<code><Window x:Class="CalendarGenerator.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1"
        Height="300"
        Width="447">
  <Grid>
    <ListBox Margin="12,40,0,12"
             Name="eventList"
             HorizontalAlignment="Left"
             Width="134" />
  </Grid>
</Window>
</code>```

And a simple list defined as:

```<code>List<String> ListOfNames = new List<String>();
</code>```

And let's assume that the list has several names in it. How would I go about binding the List to the ListBox using as much code-behind as possible?

答:
If the data list is created in code then you're going to have to bind it in code, like so:

```<code>eventList.ItemsSource = ListOfNames;
</code>```

Now binding to a list of strings is a very simple example. Let's take a more complex one.

Say you have a person class:

```<code>public class Person {
    public string FirstName { get; set; }
    public string Surname { get; set; }
}
</code>```

To display a list of persons you could bind a list to the ListBox, but you'll end up with a listbox that displays "Person" for each entry, because you haven't told WPF how to display a person object.

To tell WPF how to visually display data objects we define a DataTemplate like so:

```<code><Window.Resources>
    <DataTemplate DataType="{x:Type l:Person}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding FirstName}"/>
            <TextBlock Text=" "/>
            <TextBlock Text="{Binding Surname}"/>
        </StackPanel>
    </DataTemplate>
</Window.Resources>
<Grid>
    <ListBox Name="listBox" />
</Grid>

public Window1() {
    InitializeComponent();
    List<Person> people = new List<Person>();
    people.Add(new Person() { FirstName = "Cameron", Surname = "MacFarland" });
    people.Add(new Person() { FirstName = "Bea", Surname = "Stollnitz" });
    people.Add(new Person() { FirstName = "Jason", Surname = "Miesionczek" });
    listBox.ItemsSource = people;
}
</code>```

This will nicely display "Firstname Surname" in the list.

If you wanted to change the look to be say "Surname, Firstname" all you need to do is change the XAML to:

```<code><StackPanel Orientation="Horizontal">
    <TextBlock FontWeight="Bold" Text="{Binding Surname}"/>
    <TextBlock Text=", "/>
    <TextBlock Text="{Binding FirstName}"/>
</StackPanel>
</code>```

OwnerDisplayName: Jason Miesionczek

Body:
Let's say, for instance, I have the following extremely simple window:

<Window x:Class="CalendarGenerator.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1"
        Height="300"
        Width="447">
  <Grid>
    <ListBox Margin="12,40,0,12"
             Name="eventList"
             HorizontalAlignment="Left"
             Width="134" />
  </Grid>
</Window>

And a simple list defined as:

List<String> ListOfNames = new List<String>();

And let's assume that the list has several names in it. How would I go about binding the List to the ListBox using as much code-behind as possible?

Body:
If the data list is created in code then you're going to have to bind it in code, like so:

eventList.ItemsSource = ListOfNames;

Now binding to a list of strings is a very simple example. Let's take a more complex one.

Say you have a person class:

public class Person {
    public string FirstName { get; set; }
    public string Surname { get; set; }
}

To display a list of persons you could bind a list to the ListBox, but you'll end up with a listbox that displays "Person" for each entry, because you haven't told WPF how to display a person object.

To tell WPF how to visually display data objects we define a DataTemplate like so:

<Window.Resources>
    <DataTemplate DataType="{x:Type l:Person}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding FirstName}"/>
            <TextBlock Text=" "/>
            <TextBlock Text="{Binding Surname}"/>
        </StackPanel>
    </DataTemplate>
</Window.Resources>
<Grid>
    <ListBox Name="listBox" />
</Grid>

public Window1() {
    InitializeComponent();
    List<Person> people = new List<Person>();
    people.Add(new Person() { FirstName = "Cameron", Surname = "MacFarland" });
    people.Add(new Person() { FirstName = "Bea", Surname = "Stollnitz" });
    people.Add(new Person() { FirstName = "Jason", Surname = "Miesionczek" });
    listBox.ItemsSource = people;
}

This will nicely display "Firstname Surname" in the list.

If you wanted to change the look to be say "Surname, Firstname" all you need to do is change the XAML to:

<StackPanel Orientation="Horizontal">
    <TextBlock FontWeight="Bold" Text="{Binding Surname}"/>
    <TextBlock Text=", "/>
    <TextBlock Text="{Binding FirstName}"/>
</StackPanel>

OwnerDisplayName: Cameron MacFarland


问:
What is the best way of showing progress on an Ajax call?
I have an Ajax call that updates 5,000 records in a database so this takes a lot of time.  I have an Ajax "Loading image" showing that something is happening, but I am looking for a better way to show "Updating  50 of 5000 . . .", "Updating 200 of 5000", or something like that.

What is the best way to do something like this in Ajax / jQuery without doing 5000 different posts?

答:
I once did something similar this way (similar to Zain Shaikh, but simpler):

On the server

```<code>int toUpdate = 5000;
int updated = 0;
int prev = updated;
while(updated < toUpdate)
{
    updated = getAlreadyUpdatedRows();
    flushToClient(generateZeroSequenceOfLength(updated - prev));
    prev = updated;
    sleep(500);
}
closeStream();
</code>```

On the client

Follow the Zain Shaikh path but on ProcessInput simply resize your progress bar according to the ratio between the number of records to update and the input.length.

This solution often trades client side complexity for network bandwidth.

Do not mix this server activity with an eventual file import, unless you really know what you are doing.
You would be trading db queries (the select for counting the updated rows) for stability: what if the user change page? There's no problem for the progress bar, but the import would not be completed.

Body:
I once did something similar this way (similar to Zain Shaikh, but simpler):

On the server

int toUpdate = 5000;
int updated = 0;
int prev = updated;
while(updated < toUpdate)
{
    updated = getAlreadyUpdatedRows();
    flushToClient(generateZeroSequenceOfLength(updated - prev));
    prev = updated;
    sleep(500);
}
closeStream();

On the client

Follow the Zain Shaikh path but on ProcessInput simply resize your progress bar according to the ratio between the number of records to update and the input.length.

This solution often trades client side complexity for network bandwidth.

Do not mix this server activity with an eventual file import, unless you really know what you are doing.
You would be trading db queries (the select for counting the updated rows) for stability: what if the user change page? There's no problem for the progress bar, but the import would not be completed.


答:
In the Conditional Formatting Rules Manager (Home->Conditional Formatting->Manage Rules...) make sure your conditional format is correct in the "Rule" Column and then make sure the "Applies to" column is also correct.  I suspect this is your problem.

Try changing the rule to: =$C2=1
And change range of application to: =$A$2:$C$10 (or whatever the C column goes to)

Title: Conditional formatting: highlighting rows based on condition


问:
How to generate an authorization code using PayPal-Ruby-SDK for future payment?
I am trying to generate access token for paypal for future payment using  PayPal-Ruby-SDK example.

```<code>it "Exchange Authorization Code for Refresh / Access Tokens" do
    # put your authorization code for testing here
    auth_code = ''
    if auth_code != ''
      access_token  = FuturePayment.exch_token(auth_code)
      access_token.should_not be_nil
    end
end
</code>```

It requires an authorization code which I am unable to find how to generate.
Any Help will be highly obliged.

答: You are able to get Authorization Code only via PayPal web login flow. According to Paypal's official documentation .</p>

Body:
I am trying to generate access token for paypal for future payment using  PayPal-Ruby-SDK example.

it "Exchange Authorization Code for Refresh / Access Tokens" do
    # put your authorization code for testing here
    auth_code = ''
    if auth_code != ''
      access_token  = FuturePayment.exch_token(auth_code)
      access_token.should_not be_nil
    end
end

It requires an authorization code which I am unable to find how to generate.
Any Help will be highly obliged.


问:
Memory model of the Adreno GPU
Reading about Adreno GPU by Qualcomm being an SOC I have come up with a question that is the memory same for both of them?

If yes, is there some virtual addressing on top of of it like CUDA's Unified Virtual Addressing (UVA) ?

Also, if this is not the case is there something like the CUDA 6's unified memory model supported in here?

答:
I think it would be best if you rephrased your question due to it being ambiguous. As far as understand your question, you would like to know if Adreno GPUs have any unified memory support and unified virtual addressing support.

Starting with the basics, CUDA is Nvidia only paradigm and Adreno's use OpenCL instead. OpenCL version 2.0 specification has a support for unified memory with the name shared virtual memory (SVM). Section 3.3.3 in the specification explains how it works and the constraints https://www.khronos.org/registry/OpenCL/specs/opencl-2.0.pdf. I don't have extensive knowledge about how CUDA's UVA and unified memory model works, but in OpenCL you have different capabilities from coarse grain support to fine grain system support. You need to check the whitepaper of the Adreno GPU you want to learn about which one is supported.

Nevertheless, according to Adreno wikipedia page, https://en.wikipedia.org/wiki/Adreno, 5th generation Adreno GPUs have full OpenCL 2.0 support, which should enable at least coarse grain SVM support. Older Adreno GPUs do not support sharing any address space pointers, so you need to copy the data between CPU and GPU address spaces or use pinned memory.

Title: Memory model of the Adreno GPU


问:
jQuery Ajax get value via function?
I have created a save(id) function that will submit ajax post request. When calling a save(id). How to get value/data from save(id) before going to next step. How to solve this?

For example:

```<code>        function save(id) {
            $.ajax({
                type: "POST",
                url: "/post/",
                dataType: "json",
                contentType: 'application/json',
                data: JSON.stringify({
                    id: id,
                }),
                success: function (data) {
                 return data;
                },
                error: function (error) {
                return data;
                }
            });
        }
</code>```

Usage:

```<code>$('.btn-create').click(function () {
  var id = 123;
  data = saveArea(id); //get data from ajax request or error data?
  if (data) {
     window.location = "/post/" + data.something
  }
}
</code>```

答:
You have two options, either run the AJAX call synchronously (not recommended). Or asynchronously using callbacks

Synchronous

As @Drew_Kennedy mentions, this will freeze the page until it's finished, degrading the user experience.

```<code>function save(id) {
    return $.ajax({
        type: "POST",
        url: "/post/",
        dataType: "json",
        contentType: 'application/json',
        async: false,
        data: JSON.stringify({
            id: id,
        })
    }).responseText;
}

$('.btn-create').click(function () {
  var id = 123;
  // now this will work
  data = save(id);
  if (data) {
     window.location = "/post/" + data.something
  }
}
</code>```

Asynchronous (recommended)

This will run in the background, and allow for normal user interaction on the page.

```<code>function save(id, cb, err) {
    $.ajax({
        type: "POST",
        url: "/post/",
        dataType: "json",
        contentType: 'application/json',
        data: JSON.stringify({
            id: id,
        }),
        success: function (data) {
            cb(data);
        },
        error: err // you can do the same for success/cb: "success: cb"
    });
}

$('.btn-create').click(function () {
  var id = 123;
  save(id,
    // what to do on success
    function(data) {
      // data is available here in the callback
      if (data) {
          window.location = "/post/" + data.something
      }
    },
    // what to do on failure
    function(data) {
      alert(data);
    }
  });
}
</code>```

Title: jQuery Ajax get value via function?

Body:
I have created a save(id) function that will submit ajax post request. When calling a save(id). How to get value/data from save(id) before going to next step. How to solve this?

For example:

        function save(id) {
            $.ajax({
                type: "POST",
                url: "/post/",
                dataType: "json",
                contentType: 'application/json',
                data: JSON.stringify({
                    id: id,
                }),
                success: function (data) {
                 return data;
                },
                error: function (error) {
                return data;
                }
            });
        }

Usage:

$('.btn-create').click(function () {
  var id = 123;
  data = saveArea(id); //get data from ajax request or error data?
  if (data) {
     window.location = "/post/" + data.something
  }
}

Body:
You have two options, either run the AJAX call synchronously (not recommended). Or asynchronously using callbacks

Synchronous

As @Drew_Kennedy mentions, this will freeze the page until it's finished, degrading the user experience.

function save(id) {
    return $.ajax({
        type: "POST",
        url: "/post/",
        dataType: "json",
        contentType: 'application/json',
        async: false,
        data: JSON.stringify({
            id: id,
        })
    }).responseText;
}

$('.btn-create').click(function () {
  var id = 123;
  // now this will work
  data = save(id);
  if (data) {
     window.location = "/post/" + data.something
  }
}

Asynchronous (recommended)

This will run in the background, and allow for normal user interaction on the page.

function save(id, cb, err) {
    $.ajax({
        type: "POST",
        url: "/post/",
        dataType: "json",
        contentType: 'application/json',
        data: JSON.stringify({
            id: id,
        }),
        success: function (data) {
            cb(data);
        },
        error: err // you can do the same for success/cb: "success: cb"
    });
}

$('.btn-create').click(function () {
  var id = 123;
  save(id,
    // what to do on success
    function(data) {
      // data is available here in the callback
      if (data) {
          window.location = "/post/" + data.something
      }
    },
    // what to do on failure
    function(data) {
      alert(data);
    }
  });
}


问:
Rails looking for template for JSON requests
In my routes.rb I have:

```<code>resources :workouts
</code>```

In my workouts controller I have:

```<code>def show
  respond_to do |format|
    format.html
    format.json { render :json => "Success" }
  end
end
</code>```

But when I go to /workouts/1.json, I receive the following:

Template is missing

Missing template workouts/show, application/show with {:locale=>[:en], :formats=>[:json], :handlers=>[:erb, :builder, :coffee]}. Searched in: * "/home/rails/app/views"

Which appears to show that the format is what it should be but it's still searching for a view. This same code functions in other controllers with identical setups just fine. Also, going to /workouts/1 for the html view seems to work just fine, though it also renders the html view properly when the format.html is removed.

答: You would try with /workouts.json</p>

Body:
In my routes.rb I have:

resources :workouts

In my workouts controller I have:

def show
  respond_to do |format|
    format.html
    format.json { render :json => "Success" }
  end
end

But when I go to /workouts/1.json, I receive the following:

Template is missing

Missing template workouts/show, application/show with {:locale=>[:en], :formats=>[:json], :handlers=>[:erb, :builder, :coffee]}. Searched in: * "/home/rails/app/views"

Which appears to show that the format is what it should be but it's still searching for a view. This same code functions in other controllers with identical setups just fine. Also, going to /workouts/1 for the html view seems to work just fine, though it also renders the html view properly when the format.html is removed.

Body: You would try with /workouts.json


问:
How to test the type of a generic interface?
I'm not sure if the title makes sense, but I hope you can understand my question with some code.

Given the following code for a publish/subscribe framework.

```<code>type
  IMessage = interface
    ['{B1794F44-F6EE-4E7B-849A-995F05897E1C}']
  end;

  ISubscriber = interface
    ['{D655967E-90C6-4613-92C5-1E5B53619EE0}']
  end;

  ISubscriberOf<T: IMessage> = interface(ISubscriber)
    procedure Consume(const message: T);
  end;

  TMessageService = class
  private
    FSubscribers: TList<ISubscriber>;
  public
    constructor Create;
    destructor Destroy; override;
    procedure SendMessage(const message: IMessage);
    procedure Subscribe(const Subscriber: ISubscriber);
    procedure Unsubscribe(const Subscriber: ISubscriber);
  end;
</code>```

That would be used like this:

```<code>TMyMessage = class(TInterfacedObject, IMessage);

TMySubscriber = class(TInterfacedObject, ISubscriberOf<TMyMessage>)
  procedure Consume(const Message: TMyMessage);
end;

TMyOtherMessage = class(TInterfacedObject, IMessage);

TMyOtherSubscriber = class(TInterfacedObject, ISubscriberOf<TMyOtherMessage>)
  procedure Consume(const Message: TOtherMessage);
end;
</code>```

How can I loop the subscribers list and send the message to the proper subscribers?

The subscribers list will have all subscribers for all types of messages. The SendMessage have to find the subscribers for the type of message provided as param and send it to whom implements the proper interface to consume that type of message.

```<code>  procedure TMessageService.SendMessage(const message: IMessage);
  var
    Subscriber: ISubscriber;
  begin
    for Subscriber in FSubscribers do
    begin
      // How to send the message only to the subscribers of the correspondent type of message
    end;
  end;
</code>```

Thanks!

BTW, this code is based on this blog post.

答:
Edit: found a way to make this less convoluted (please vote on this answer as you like this; it took quite a while to get it right).

Note it uses the new Rtti unit, so it works only for Delphi 2010 and up (I used Delphi XE for developing this, I did not yet verify this in Delphi 2010).

For the Supports, you need to store some IID GUIDs with your interfaces and a means to query them.

Since you want to use this with generics, you want to able to query the IID GUID from an interface type, not from an interface reference (as Hallvard Vassbotn showed with a hack in 2006).

The new RTTI introduced in Delphi 2010 allows you to do just that:

```<code>unit RttiUnit;

interface

type
  TRtti = record
    //1 similar to http://hallvards.blogspot.com/2006/09/hack11-get-guid-of-interface-reference.html but for the interface type, not for a reference
    class function GetInterfaceIID<T: IInterface>(var IID: TGUID): Boolean; static;
  end;

implementation

uses
  TypInfo,
  Rtti;

class function TRtti.GetInterfaceIID<T>(var IID: TGUID): Boolean;
var
  TypeInfoOfT: PTypeInfo;
  RttiContext: TRttiContext;
  RttiInterfaceType: TRttiInterfaceType;
  RttiType: TRttiType;
begin
  TypeInfoOfT := TypeInfo(T);
  RttiContext := TRttiContext.Create();

  RttiType := RttiContext.GetType(TypeInfoOfT);
  if RttiType is TRttiInterfaceType then
  begin
    RttiInterfaceType := RttiType as TRttiInterfaceType;
    IID := RttiInterfaceType.GUID;
    Result := True;
  end
  else
    Result := False;
end;

end.
</code>```

So now the changed code, which I rearranged a bit, and spread over more units to keep the overview.

ClassicMessageSubscriberUnit: has the non generic interfaces IMessage and ISubscriber (they descend from IImplementedWithClass which makes it easier to log things.

```<code>unit ClassicMessageSubscriberUnit;

interface

type
  IImplementedWithClass = interface(IInterface)
    function ToString: string;
  end;

  IMessage = interface(IImplementedWithClass)
    ['{B1794F44-F6EE-4E7B-849A-995F05897E1C}']
  end;

  ISubscriber = interface(IImplementedWithClass)
    ['{D655967E-90C6-4613-92C5-1E5B53619EE0}']
  end;

implementation

end.
</code>```

GenericSubscriberOfUnit: contains the generic ISubscriberOf interface which descends from the generic ISupporterOf and a generic base implementation called TSupporterOf:

```<code>unit GenericSubscriberOfUnit;

interface

uses
  ClassicMessageSubscriberUnit;

type
  ISupporterOf<T: IMessage> = interface(ISubscriber)
    ['{0905B3EB-B17E-4AD2-98E2-16F05D19484C}']
    function Supports(const Message: T): Boolean;
  end;

  ISubscriberOf<T: IMessage> = interface(ISupporterOf<T>)
    ['{6FD82B1D-61C6-4572-BA7D-D70DA9A73285}']
    procedure Consume(const Message: T);
  end;

type
  TSupporterOf<T: IMessage> = class(TInterfacedObject, ISubscriber, ISupporterOf<T>)
    function Supports(const Message: T): Boolean;
  end;

implementation

uses
  SysUtils,
  RttiUnit;

function TSupporterOf<T>.Supports(const Message: T): Boolean;
var
  IID: TGUID;
begin
  if TRtti.GetInterfaceIID<T>(IID) then
    Result := SysUtils.Supports(Message, IID)
  else
    Result := False;
end;

end.
</code>```

MessageServiceUnit: now only contains TMessageService, some type aliases and some actual code for managing the list so I could actually test it.

```<code>unit MessageServiceUnit;

interface

uses
  Generics.Collections,
  ClassicMessageSubscriberUnit,
  GenericSubscriberOfUnit;

type
  ISubscriberOfIMessage = ISubscriberOf<IMessage>;
  TListISubscriber = TList<ISubscriber>;

  TMessageService = class
  private
    FSubscribers: TListISubscriber;
  strict protected
    procedure Consume(const SubscriberOf: ISubscriberOfIMessage; const Message: IMessage); virtual;
  public
    constructor Create;
    destructor Destroy; override;
    procedure SendMessage(const Message: IMessage);
    procedure Subscribe(const Subscriber: ISubscriber);
    procedure Unsubscribe(const Subscriber: ISubscriber);
  end;

implementation

uses
  SysUtils;

constructor TMessageService.Create;
begin
  inherited Create();
  FSubscribers := TListISubscriber.Create();
end;

destructor TMessageService.Destroy;
begin
  FreeAndNil(FSubscribers);
  inherited Destroy();
end;

procedure TMessageService.SendMessage(const Message: IMessage);
var
  LocalMessage: IMessage;
  lSubscriber: ISubscriber;
  lSubscriberOf: ISubscriberOf<IMessage>;
begin
  for lSubscriber in FSubscribers do
  begin
    LocalMessage := Message; // to prevent premature freeing of Message
    if Supports(lSubscriber, ISubscriberOf<IMessage>, lSubscriberOf) then
      if lSubscriberOf.Supports(LocalMessage) then
        Consume(lSubscriberOf, LocalMessage);
  end;
end;

procedure TMessageService.Subscribe(const Subscriber: ISubscriber);
begin
  FSubscribers.Add(Subscriber);
end;

procedure TMessageService.Unsubscribe(const Subscriber: ISubscriber);
begin
  FSubscribers.Remove(Subscriber);
end;

procedure TMessageService.Consume(const SubscriberOf: ISubscriberOfIMessage; const Message: IMessage);
begin
  SubscriberOf.Consume(Message);
end;

end.
</code>```

Finally a unit that I used to test everything (it uses the bo-library at http://bo.codeplex.com):

```<code>unit GenericPublishSubscribeMainFormUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, LoggerInterfaceUnit, MessageServiceUnit,
  MessageSubscribersUnit, ClassicMessageSubscriberUnit;

type
  TGenericPublishSubscribeMainForm = class(TForm)
    TestPublisherButton: TButton;
    LogMemo: TMemo;
    procedure TestPublisherButtonClick(Sender: TObject);
  strict private
    FLogger: ILogger;
  strict protected
    function GetLogger: ILogger;
    property Logger: ILogger read GetLogger;
  public
    destructor Destroy; override;
  end;

type
  TLoggingMessageService = class(TMessageService)
  strict private
    FLogger: ILogger;
  strict protected
    procedure Consume(const SubscriberOf: ISubscriberOfIMessage; const Message: IMessage); override;
  public
    constructor Create(const Logger: ILogger);
    property Logger: ILogger read FLogger;
  end;

var
  GenericPublishSubscribeMainForm: TGenericPublishSubscribeMainForm;

implementation

uses
  LoggerUnit,
  OutputDebugViewLoggerUnit,
  LoggersUnit,
  MessagesUnit;

{$R *.dfm}

destructor TGenericPublishSubscribeMainForm.Destroy;
begin
  inherited Destroy;
  FLogger := nil;
end;

function TGenericPublishSubscribeMainForm.GetLogger: ILogger;
begin
  if not Assigned(FLogger) then
    FLogger :=  TTeeLogger.Create([
      TOutputDebugViewLogger.Create(),
      TStringsLogger.Create(LogMemo.Lines)
    ]);
  Result := FLogger;
end;

procedure TGenericPublishSubscribeMainForm.TestPublisherButtonClick(Sender: TObject);
var
  LoggingMessageService: TLoggingMessageService;
begin
  LoggingMessageService := TLoggingMessageService.Create(Logger);
  try
    LoggingMessageService.Subscribe(TMySubscriber.Create() as ISubscriber);
    LoggingMessageService.Subscribe(TMyOtherSubscriber.Create() as ISubscriber);
    LoggingMessageService.SendMessage(TMyMessage.Create());
    LoggingMessageService.SendMessage(TMyOtherMessage.Create());
  finally
    LoggingMessageService.Free;
  end;
end;

constructor TLoggingMessageService.Create(const Logger: ILogger);
begin
  inherited Create();
  FLogger := Logger;
end;

procedure TLoggingMessageService.Consume(const SubscriberOf: ISubscriberOfIMessage; const Message: IMessage);
var
  MessageImplementedWithClass: IImplementedWithClass;
  MessageString: string;
  SubscribeImplementedWithClass: IImplementedWithClass;
  SubscriberOfString: string;
begin
  SubscribeImplementedWithClass := SubscriberOf;
  MessageImplementedWithClass := Message;
  SubscriberOfString := SubscribeImplementedWithClass.ToString;
  MessageString := MessageImplementedWithClass.ToString; // wrong VMT here, Delphi XE SP2
  Logger.Log('Consume(SubscriberOf: %s, Message:%s);',
    [SubscriberOfString, MessageString]);
//    [SubscriberOf.ClassType.ClassName, Message.ClassType.ClassName]);
  inherited Consume(SubscriberOf, Message);
end;

end.
</code>```

--jeroen

Old solution:

This might do it, but I still find the solution a bit convoluted.

MessageServiceUnit: ISubscriberOf now has a GUID and a Supports method to check if the IMessage is in fact supported.

```<code>unit MessageServiceUnit;

interface

uses
  Generics.Collections;

type
  IMessage = interface(IInterface)
    ['{B1794F44-F6EE-4E7B-849A-995F05897E1C}']
  end;

  ISubscriber = interface(IInterface)
    ['{D655967E-90C6-4613-92C5-1E5B53619EE0}']
  end;

  ISubscriberOf<T: IMessage> = interface(ISubscriber)
    ['{6FD82B1D-61C6-4572-BA7D-D70DA9A73285}']
    procedure Consume(const Message: T);
    function Supports(const Message: T): Boolean;
  end;

  TMessageService = class
  private
    FSubscribers: TList<ISubscriber>;
  public
    constructor Create;
    destructor Destroy; override;
    procedure SendMessage(const Message: IMessage);
    procedure Subscribe(const Subscriber: ISubscriber);
    procedure Unsubscribe(const Subscriber: ISubscriber);
  end;

implementation

uses
  SysUtils;

constructor TMessageService.Create;
begin
  inherited Create();
end;

destructor TMessageService.Destroy;
begin
  inherited Destroy();
end;

procedure TMessageService.SendMessage(const Message: IMessage);
var
  lSubscriber: ISubscriber;
  lSubscriberOf: ISubscriberOf<IMessage>;
begin
  for lSubscriber in FSubscribers do
  begin
    if Supports(lSubscriber, ISubscriberOf<IMessage>, lSubscriberOf) then
      if lSubscriberOf.Supports(Message) then
        lSubscriberOf.Consume(Message);
  end;
end;

procedure TMessageService.Subscribe(const Subscriber: ISubscriber);
begin
  FSubscribers.Add(Subscriber);
end;

procedure TMessageService.Unsubscribe(const Subscriber: ISubscriber);
begin
  FSubscribers.Remove(Subscriber);
end;

end.
</code>```

MessagesUnit: Messages each have an interface with a GUID so Supports can check for the GUID.

```<code>unit MessagesUnit;

interface

uses
  MessageServiceUnit;

type
  IMyMessage = interface(IMessage)
    ['{84B42EC8-CAC0-44B4-97A8-05AE5B636236}']
  end;
  TMyMessage = class(TInterfacedObject, IMessage, IMyMessage);

  IMyOtherMessage = interface(IMessage)
    ['{AB323765-FF7B-4852-91AA-B7ECC1845B41}']
  end;
  TMyOtherMessage = class(TInterfacedObject, IMessage, IMyOtherMessage);

implementation

end.
</code>```

MessageSubscribersUnit: all subscribers have a Supports method checking the right GUID.

```<code>unit MessageSubscribersUnit;

interface

uses
  MessagesUnit, MessageServiceUnit;

type
  TMySubscriber = class(TInterfacedObject, ISubscriberOf<IMyMessage>)
    procedure Consume(const Message: IMyMessage);
    function Supports(const Message: IMyMessage): Boolean;
  end;

  TMyOtherSubscriber = class(TInterfacedObject, ISubscriberOf<IMyOtherMessage>)
    procedure Consume(const Message: IMyOtherMessage);
    function Supports(const Message: IMyOtherMessage): Boolean;
  end;

implementation

uses
  SysUtils;

procedure TMySubscriber.Consume(const Message: IMyMessage);
begin
  //
end;

function TMySubscriber.Supports(const Message: IMyMessage): Boolean;
begin
  Result := SysUtils.Supports(Message,  IMyMessage);
end;

procedure TMyOtherSubscriber.Consume(const Message: IMyOtherMessage);
begin
  //
end;

function TMyOtherSubscriber.Supports(const Message: IMyOtherMessage): Boolean;
begin
  Result := SysUtils.Supports(Message,  IMyOtherMessage);
end;

end.
</code>```

MessagesUnit: contains the specific messages (both the interface and class types), which contain the IID GUIDs to distinguish them with Supports.

```<code>unit MessagesUnit;

interface

uses
  MessageServiceUnit,
  ClassicMessageSubscriberUnit;

type
  IMyMessage = interface(IMessage)
    ['{84B42EC8-CAC0-44B4-97A8-05AE5B636236}']
  end;
  TMyMessage = class(TInterfacedObject, IMessage, IMyMessage);

  IMyOtherMessage = interface(IMessage)
    ['{AB323765-FF7B-4852-91AA-B7ECC1845B41}']
  end;
  TMyOtherMessage = class(TInterfacedObject, IMessage, IMyOtherMessage);

implementation

end.
</code>```

MessageSubscribersUnit: contains the specific subscribers (both the interface and class types), which now do not need the Supports method any more: they only contain the Consume method.

```<code>unit MessageSubscribersUnit;

interface

uses
  MessagesUnit,
  MessageServiceUnit,
  GenericSubscriberOfUnit,
  ClassicMessageSubscriberUnit;

type
  TMySubscriber = class(TSupporterOf<IMyMessage>, ISubscriber, ISubscriberOf<IMyMessage>)
    procedure Consume(const Message: IMyMessage);
  end;

  TMyOtherSubscriber = class(TSupporterOf<IMyOtherMessage>, ISubscriber, ISubscriberOf<IMyOtherMessage>)
    procedure Consume(const Message: IMyOtherMessage);
  end;

implementation

uses
  SysUtils;

procedure TMySubscriber.Consume(const Message: IMyMessage);
begin
  //
end;

procedure TMyOtherSubscriber.Consume(const Message: IMyOtherMessage);
begin
  //
end;

end.
</code>```

--jeroen

Body:
I'm not sure if the title makes sense, but I hope you can understand my question with some code.

Given the following code for a publish/subscribe framework.

type
  IMessage = interface
    ['{B1794F44-F6EE-4E7B-849A-995F05897E1C}']
  end;

  ISubscriber = interface
    ['{D655967E-90C6-4613-92C5-1E5B53619EE0}']
  end;

  ISubscriberOf<T: IMessage> = interface(ISubscriber)
    procedure Consume(const message: T);
  end;

  TMessageService = class
  private
    FSubscribers: TList<ISubscriber>;
  public
    constructor Create;
    destructor Destroy; override;
    procedure SendMessage(const message: IMessage);
    procedure Subscribe(const Subscriber: ISubscriber);
    procedure Unsubscribe(const Subscriber: ISubscriber);
  end;

That would be used like this:

TMyMessage = class(TInterfacedObject, IMessage);

TMySubscriber = class(TInterfacedObject, ISubscriberOf<TMyMessage>)
  procedure Consume(const Message: TMyMessage);
end;

TMyOtherMessage = class(TInterfacedObject, IMessage);

TMyOtherSubscriber = class(TInterfacedObject, ISubscriberOf<TMyOtherMessage>)
  procedure Consume(const Message: TOtherMessage);
end;

How can I loop the subscribers list and send the message to the proper subscribers?

The subscribers list will have all subscribers for all types of messages. The SendMessage have to find the subscribers for the type of message provided as param and send it to whom implements the proper interface to consume that type of message.

  procedure TMessageService.SendMessage(const message: IMessage);
  var
    Subscriber: ISubscriber;
  begin
    for Subscriber in FSubscribers do
    begin
      // How to send the message only to the subscribers of the correspondent type of message
    end;
  end;

Thanks!

BTW, this code is based on this blog post.

Body:
Edit: found a way to make this less convoluted (please vote on this answer as you like this; it took quite a while to get it right).

Note it uses the new Rtti unit, so it works only for Delphi 2010 and up (I used Delphi XE for developing this, I did not yet verify this in Delphi 2010).

For the Supports, you need to store some IID GUIDs with your interfaces and a means to query them.

Since you want to use this with generics, you want to able to query the IID GUID from an interface type, not from an interface reference (as Hallvard Vassbotn showed with a hack in 2006).

The new RTTI introduced in Delphi 2010 allows you to do just that:

unit RttiUnit;

interface

type
  TRtti = record
    //1 similar to http://hallvards.blogspot.com/2006/09/hack11-get-guid-of-interface-reference.html but for the interface type, not for a reference
    class function GetInterfaceIID<T: IInterface>(var IID: TGUID): Boolean; static;
  end;

implementation

uses
  TypInfo,
  Rtti;

class function TRtti.GetInterfaceIID<T>(var IID: TGUID): Boolean;
var
  TypeInfoOfT: PTypeInfo;
  RttiContext: TRttiContext;
  RttiInterfaceType: TRttiInterfaceType;
  RttiType: TRttiType;
begin
  TypeInfoOfT := TypeInfo(T);
  RttiContext := TRttiContext.Create();

  RttiType := RttiContext.GetType(TypeInfoOfT);
  if RttiType is TRttiInterfaceType then
  begin
    RttiInterfaceType := RttiType as TRttiInterfaceType;
    IID := RttiInterfaceType.GUID;
    Result := True;
  end
  else
    Result := False;
end;

end.

So now the changed code, which I rearranged a bit, and spread over more units to keep the overview.

ClassicMessageSubscriberUnit: has the non generic interfaces IMessage and ISubscriber (they descend from IImplementedWithClass which makes it easier to log things.

unit ClassicMessageSubscriberUnit;

interface

type
  IImplementedWithClass = interface(IInterface)
    function ToString: string;
  end;

  IMessage = interface(IImplementedWithClass)
    ['{B1794F44-F6EE-4E7B-849A-995F05897E1C}']
  end;

  ISubscriber = interface(IImplementedWithClass)
    ['{D655967E-90C6-4613-92C5-1E5B53619EE0}']
  end;

implementation

end.

GenericSubscriberOfUnit: contains the generic ISubscriberOf interface which descends from the generic ISupporterOf and a generic base implementation called TSupporterOf:

unit GenericSubscriberOfUnit;

interface

uses
  ClassicMessageSubscriberUnit;

type
  ISupporterOf<T: IMessage> = interface(ISubscriber)
    ['{0905B3EB-B17E-4AD2-98E2-16F05D19484C}']
    function Supports(const Message: T): Boolean;
  end;

  ISubscriberOf<T: IMessage> = interface(ISupporterOf<T>)
    ['{6FD82B1D-61C6-4572-BA7D-D70DA9A73285}']
    procedure Consume(const Message: T);
  end;

type
  TSupporterOf<T: IMessage> = class(TInterfacedObject, ISubscriber, ISupporterOf<T>)
    function Supports(const Message: T): Boolean;
  end;

implementation

uses
  SysUtils,
  RttiUnit;

function TSupporterOf<T>.Supports(const Message: T): Boolean;
var
  IID: TGUID;
begin
  if TRtti.GetInterfaceIID<T>(IID) then
    Result := SysUtils.Supports(Message, IID)
  else
    Result := False;
end;

end.

MessageServiceUnit: now only contains TMessageService, some type aliases and some actual code for managing the list so I could actually test it.

unit MessageServiceUnit;

interface

uses
  Generics.Collections,
  ClassicMessageSubscriberUnit,
  GenericSubscriberOfUnit;

type
  ISubscriberOfIMessage = ISubscriberOf<IMessage>;
  TListISubscriber = TList<ISubscriber>;

  TMessageService = class
  private
    FSubscribers: TListISubscriber;
  strict protected
    procedure Consume(const SubscriberOf: ISubscriberOfIMessage; const Message: IMessage); virtual;
  public
    constructor Create;
    destructor Destroy; override;
    procedure SendMessage(const Message: IMessage);
    procedure Subscribe(const Subscriber: ISubscriber);
    procedure Unsubscribe(const Subscriber: ISubscriber);
  end;

implementation

uses
  SysUtils;

constructor TMessageService.Create;
begin
  inherited Create();
  FSubscribers := TListISubscriber.Create();
end;

destructor TMessageService.Destroy;
begin
  FreeAndNil(FSubscribers);
  inherited Destroy();
end;

procedure TMessageService.SendMessage(const Message: IMessage);
var
  LocalMessage: IMessage;
  lSubscriber: ISubscriber;
  lSubscriberOf: ISubscriberOf<IMessage>;
begin
  for lSubscriber in FSubscribers do
  begin
    LocalMessage := Message; // to prevent premature freeing of Message
    if Supports(lSubscriber, ISubscriberOf<IMessage>, lSubscriberOf) then
      if lSubscriberOf.Supports(LocalMessage) then
        Consume(lSubscriberOf, LocalMessage);
  end;
end;

procedure TMessageService.Subscribe(const Subscriber: ISubscriber);
begin
  FSubscribers.Add(Subscriber);
end;

procedure TMessageService.Unsubscribe(const Subscriber: ISubscriber);
begin
  FSubscribers.Remove(Subscriber);
end;

procedure TMessageService.Consume(const SubscriberOf: ISubscriberOfIMessage; const Message: IMessage);
begin
  SubscriberOf.Consume(Message);
end;

end.

Finally a unit that I used to test everything (it uses the bo-library at http://bo.codeplex.com):

unit GenericPublishSubscribeMainFormUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, LoggerInterfaceUnit, MessageServiceUnit,
  MessageSubscribersUnit, ClassicMessageSubscriberUnit;

type
  TGenericPublishSubscribeMainForm = class(TForm)
    TestPublisherButton: TButton;
    LogMemo: TMemo;
    procedure TestPublisherButtonClick(Sender: TObject);
  strict private
    FLogger: ILogger;
  strict protected
    function GetLogger: ILogger;
    property Logger: ILogger read GetLogger;
  public
    destructor Destroy; override;
  end;

type
  TLoggingMessageService = class(TMessageService)
  strict private
    FLogger: ILogger;
  strict protected
    procedure Consume(const SubscriberOf: ISubscriberOfIMessage; const Message: IMessage); override;
  public
    constructor Create(const Logger: ILogger);
    property Logger: ILogger read FLogger;
  end;

var
  GenericPublishSubscribeMainForm: TGenericPublishSubscribeMainForm;

implementation

uses
  LoggerUnit,
  OutputDebugViewLoggerUnit,
  LoggersUnit,
  MessagesUnit;

{$R *.dfm}

destructor TGenericPublishSubscribeMainForm.Destroy;
begin
  inherited Destroy;
  FLogger := nil;
end;

function TGenericPublishSubscribeMainForm.GetLogger: ILogger;
begin
  if not Assigned(FLogger) then
    FLogger :=  TTeeLogger.Create([
      TOutputDebugViewLogger.Create(),
      TStringsLogger.Create(LogMemo.Lines)
    ]);
  Result := FLogger;
end;

procedure TGenericPublishSubscribeMainForm.TestPublisherButtonClick(Sender: TObject);
var
  LoggingMessageService: TLoggingMessageService;
begin
  LoggingMessageService := TLoggingMessageService.Create(Logger);
  try
    LoggingMessageService.Subscribe(TMySubscriber.Create() as ISubscriber);
    LoggingMessageService.Subscribe(TMyOtherSubscriber.Create() as ISubscriber);
    LoggingMessageService.SendMessage(TMyMessage.Create());
    LoggingMessageService.SendMessage(TMyOtherMessage.Create());
  finally
    LoggingMessageService.Free;
  end;
end;

constructor TLoggingMessageService.Create(const Logger: ILogger);
begin
  inherited Create();
  FLogger := Logger;
end;

procedure TLoggingMessageService.Consume(const SubscriberOf: ISubscriberOfIMessage; const Message: IMessage);
var
  MessageImplementedWithClass: IImplementedWithClass;
  MessageString: string;
  SubscribeImplementedWithClass: IImplementedWithClass;
  SubscriberOfString: string;
begin
  SubscribeImplementedWithClass := SubscriberOf;
  MessageImplementedWithClass := Message;
  SubscriberOfString := SubscribeImplementedWithClass.ToString;
  MessageString := MessageImplementedWithClass.ToString; // wrong VMT here, Delphi XE SP2
  Logger.Log('Consume(SubscriberOf: %s, Message:%s);',
    [SubscriberOfString, MessageString]);
//    [SubscriberOf.ClassType.ClassName, Message.ClassType.ClassName]);
  inherited Consume(SubscriberOf, Message);
end;

end.

--jeroen

Old solution:

This might do it, but I still find the solution a bit convoluted.

MessageServiceUnit: ISubscriberOf now has a GUID and a Supports method to check if the IMessage is in fact supported.

unit MessageServiceUnit;

interface

uses
  Generics.Collections;

type
  IMessage = interface(IInterface)
    ['{B1794F44-F6EE-4E7B-849A-995F05897E1C}']
  end;

  ISubscriber = interface(IInterface)
    ['{D655967E-90C6-4613-92C5-1E5B53619EE0}']
  end;

  ISubscriberOf<T: IMessage> = interface(ISubscriber)
    ['{6FD82B1D-61C6-4572-BA7D-D70DA9A73285}']
    procedure Consume(const Message: T);
    function Supports(const Message: T): Boolean;
  end;

  TMessageService = class
  private
    FSubscribers: TList<ISubscriber>;
  public
    constructor Create;
    destructor Destroy; override;
    procedure SendMessage(const Message: IMessage);
    procedure Subscribe(const Subscriber: ISubscriber);
    procedure Unsubscribe(const Subscriber: ISubscriber);
  end;

implementation

uses
  SysUtils;

constructor TMessageService.Create;
begin
  inherited Create();
end;

destructor TMessageService.Destroy;
begin
  inherited Destroy();
end;

procedure TMessageService.SendMessage(const Message: IMessage);
var
  lSubscriber: ISubscriber;
  lSubscriberOf: ISubscriberOf<IMessage>;
begin
  for lSubscriber in FSubscribers do
  begin
    if Supports(lSubscriber, ISubscriberOf<IMessage>, lSubscriberOf) then
      if lSubscriberOf.Supports(Message) then
        lSubscriberOf.Consume(Message);
  end;
end;

procedure TMessageService.Subscribe(const Subscriber: ISubscriber);
begin
  FSubscribers.Add(Subscriber);
end;

procedure TMessageService.Unsubscribe(const Subscriber: ISubscriber);
begin
  FSubscribers.Remove(Subscriber);
end;

end.

MessagesUnit: Messages each have an interface with a GUID so Supports can check for the GUID.

unit MessagesUnit;

interface

uses
  MessageServiceUnit;

type
  IMyMessage = interface(IMessage)
    ['{84B42EC8-CAC0-44B4-97A8-05AE5B636236}']
  end;
  TMyMessage = class(TInterfacedObject, IMessage, IMyMessage);

  IMyOtherMessage = interface(IMessage)
    ['{AB323765-FF7B-4852-91AA-B7ECC1845B41}']
  end;
  TMyOtherMessage = class(TInterfacedObject, IMessage, IMyOtherMessage);

implementation

end.

MessageSubscribersUnit: all subscribers have a Supports method checking the right GUID.

unit MessageSubscribersUnit;

interface

uses
  MessagesUnit, MessageServiceUnit;

type
  TMySubscriber = class(TInterfacedObject, ISubscriberOf<IMyMessage>)
    procedure Consume(const Message: IMyMessage);
    function Supports(const Message: IMyMessage): Boolean;
  end;

  TMyOtherSubscriber = class(TInterfacedObject, ISubscriberOf<IMyOtherMessage>)
    procedure Consume(const Message: IMyOtherMessage);
    function Supports(const Message: IMyOtherMessage): Boolean;
  end;

implementation

uses
  SysUtils;

procedure TMySubscriber.Consume(const Message: IMyMessage);
begin
  //
end;

function TMySubscriber.Supports(const Message: IMyMessage): Boolean;
begin
  Result := SysUtils.Supports(Message,  IMyMessage);
end;

procedure TMyOtherSubscriber.Consume(const Message: IMyOtherMessage);
begin
  //
end;

function TMyOtherSubscriber.Supports(const Message: IMyOtherMessage): Boolean;
begin
  Result := SysUtils.Supports(Message,  IMyOtherMessage);
end;

end.

MessagesUnit: contains the specific messages (both the interface and class types), which contain the IID GUIDs to distinguish them with Supports.

unit MessagesUnit;

interface

uses
  MessageServiceUnit,
  ClassicMessageSubscriberUnit;

type
  IMyMessage = interface(IMessage)
    ['{84B42EC8-CAC0-44B4-97A8-05AE5B636236}']
  end;
  TMyMessage = class(TInterfacedObject, IMessage, IMyMessage);

  IMyOtherMessage = interface(IMessage)
    ['{AB323765-FF7B-4852-91AA-B7ECC1845B41}']
  end;
  TMyOtherMessage = class(TInterfacedObject, IMessage, IMyOtherMessage);

implementation

end.

MessageSubscribersUnit: contains the specific subscribers (both the interface and class types), which now do not need the Supports method any more: they only contain the Consume method.

unit MessageSubscribersUnit;

interface

uses
  MessagesUnit,
  MessageServiceUnit,
  GenericSubscriberOfUnit,
  ClassicMessageSubscriberUnit;

type
  TMySubscriber = class(TSupporterOf<IMyMessage>, ISubscriber, ISubscriberOf<IMyMessage>)
    procedure Consume(const Message: IMyMessage);
  end;

  TMyOtherSubscriber = class(TSupporterOf<IMyOtherMessage>, ISubscriber, ISubscriberOf<IMyOtherMessage>)
    procedure Consume(const Message: IMyOtherMessage);
  end;

implementation

uses
  SysUtils;

procedure TMySubscriber.Consume(const Message: IMyMessage);
begin
  //
end;

procedure TMyOtherSubscriber.Consume(const Message: IMyOtherMessage);
begin
  //
end;

end.

--jeroen


问:
Why use size of character pointer

What is the meaning of this statement?

```<code>char *str[10];
</code>```

Why do we need to specify the size?

答:
As already noted in the comments, char *str[10]; depicts an array of char pointers.  This would be useful, for example, if the length of strings this object will contain is not known until run-time.  Once at run-time, it is determined that the length of string for each char * needs to be 25 (for example), then memory can be dynamically created on the heap:

```<code>for(i=0;i<10;i++)
{
    str[i] = calloc(26,1);//room for 25 char plus NULL terminator for each char *
}
</code>```

If string length is known before run-time, then the array of char arrays can be created on the stack as:

```<code>char str[10][26]
</code>```

Either of these methods work to create arrays of strings.  The first method requires that memory be freed when finished using the object:

```<code>for(i=0;i<10;i++)
{
    if(str[i]) free(str[i]);
}
</code>```

Title: Why use size of character pointer

Body:
What is the meaning of this statement?

char *str[10];

Why do we need to specify the size?

Body:
As already noted in the comments, char *str[10]; depicts an array of char pointers.  This would be useful, for example, if the length of strings this object will contain is not known until run-time.  Once at run-time, it is determined that the length of string for each char * needs to be 25 (for example), then memory can be dynamically created on the heap:

for(i=0;i<10;i++)
{
    str[i] = calloc(26,1);//room for 25 char plus NULL terminator for each char *
}

If string length is known before run-time, then the array of char arrays can be created on the stack as:

char str[10][26]

Either of these methods work to create arrays of strings.  The first method requires that memory be freed when finished using the object:

for(i=0;i<10;i++)
{
    if(str[i]) free(str[i]);
}


问:
Columns with unequal length and headers buried within these columns
I have some data where every second column corresponds to a specific time, each time period have respectively 'buy' and 'sell' positions, and each of these position have two factors (as seen below). However the columns have unequal lengths, and so the 'sell' options start at different rows (buried among the values).

```<code>time, time1, time,  time2,  time, time3
buy,       , buy,        ,  buy,
factor1,  1, factor1,    2, factor1,  3
factor2,  4, factor2,    5, factor2,  6
factor1,  7, factor1,    8, factor1,  9
factor2, 10, factor2,   11, factor2, 12
factor1, 13, sell,        , factor1, 14
factor2, 15, factor1,   16, factor2, 17
sell,      , factor2,   18, factor1, 19
factor1, 20, ,            , factor2, 21,
factor2, 22, ,            , sell,
,          , ,            , factor1, 23
,          , ,            , factor2, 24
,          , ,            , factor1, 25
,          , ,            , factor2, 26
</code>```

Ultimately, I would like I table structured like below.

```<code>time,   position,   factor,     value
time1,  buy,        factor1,    1
time1,  buy,        factor2,    4
time1,  buy,        factor1,    7
time1,  buy,        factor2,    10
time1,  buy,        factor1,    13
time1,  buy,        factor2,    15
time1,  sell,       factor1,    20
time1,  sell,       factor2,    22
time2,  buy,        factor1,    2
time2,  buy,        factor2,    5
time2,  buy,        factor1,    8
time2,  buy,        factor2,    11
time2,  sell,       factor1,    16
time2,  sell,       factor2,    18
time3,  buy,        factor1,    3
time3,  buy,        factor2,    6
time3,  buy,        factor1,    9
time3,  buy,        factor2,    12
time3,  buy,        factor1,    14
time3,  buy,        factor2,    17
time3,  buy,        factor1,    19
time3,  buy,        factor2,    21
time3,  sell,       factor1,    23
time3,  sell,       factor2,    24
time3,  sell,       factor1,    25
time3,  sell,       factor2,    26
</code>```

I am able to extract the indices and then create respectively 'buy' and 'sell' list in R. But I am unsure whether this is the easiest approach (I have many such files, and would prefer a fast automatic method). I am also open to making the transformation i Python, rather than R.

```<code># For each column find the index of buy, sell (and the corresponding empty cell)
idx = apply(data, 2, function(x) which(x %in% c("buy","sell",""))[1:3] )
# NA indicates that the empty cell is the last
idx[is.na(idx)] = nrow(data)

i = 0
buy = list( apply(idx, 2, function(x) {
  i <<- i+1
  data[seq(x[1]+1,x[2]),i]
}) )
i = 0
sell = list( apply(idx, 2, function(x) {
  i <<- i+1
  data[seq(x[2]+1,x[3]),i]
}) )
</code>```

答:
I decidd to combine the 3 sets of 2 columns first in one long format data set. Then fill in the position column by last known value carried forward (tidyr::fill), and filter out the rubbish, by filtering on the column value.

Here is the working example:

```<code>library(dplyr)
library(tidyr)

str <- "
time, time1, time,  time2,  time, time3
buy,       , buy,        ,  buy,
factor1,  1, factor1,    2, factor1,  3
factor2,  4, factor2,    5, factor2,  6
factor1,  7, factor1,    8, factor1,  9
factor2, 10, factor2,   11, factor2, 12
factor1, 13, sell,        , factor1, 14
factor2, 15, factor1,   16, factor2, 17
sell,      , factor2,   18, factor1, 19
factor1, 20, ,            , factor2, 21,
factor2, 22, ,            , sell,
,          , ,            , factor1, 23
,          , ,            , factor2, 24
,          , ,            , factor1, 25
,          , ,            , factor2, 26
"

strfile <- textConnection(str)

raw <- read.table(strfile, header = F, sep = ",", stringsAsFactors = F)

library(dplyr)
library(tidyr)
dt <- do.call(rbind, lapply(1:3, function(x) {
  p <- raw[,c(x*2-1,x*2)]
  names(p) <- c('factor', 'value')
  p$time <- x
  p
  })
)

dt %>%
  mutate(position = if_else(trimws(factor) %in% c('buy','sell'),as.character(factor),as.character(NA)),
         value = as.numeric(value)) %>%
  fill(position) %>% filter(!is.na(value))
</code>```

Result:

```<code>factor value time position
1   factor1     1    1      buy
2   factor2     4    1      buy
3   factor1     7    1      buy
4   factor2    10    1      buy
5   factor1    13    1      buy
6   factor2    15    1      buy
7   factor1    20    1     sell
8   factor2    22    1     sell
9   factor1     2    2      buy
10  factor2     5    2      buy
11  factor1     8    2      buy
12  factor2    11    2      buy
13  factor1    16    2     sell
14  factor2    18    2     sell
15  factor1     3    3      buy
16  factor2     6    3      buy
17  factor1     9    3      buy
18  factor2    12    3      buy
19  factor1    14    3      buy
20  factor2    17    3      buy
21  factor1    19    3      buy
22  factor2    21    3      buy
23  factor1    23    3     sell
24  factor2    24    3     sell
25  factor1    25    3     sell
26  factor2    26    3     sell
</code>```

Body:
I have some data where every second column corresponds to a specific time, each time period have respectively 'buy' and 'sell' positions, and each of these position have two factors (as seen below). However the columns have unequal lengths, and so the 'sell' options start at different rows (buried among the values).

time, time1, time,  time2,  time, time3
buy,       , buy,        ,  buy,
factor1,  1, factor1,    2, factor1,  3
factor2,  4, factor2,    5, factor2,  6
factor1,  7, factor1,    8, factor1,  9
factor2, 10, factor2,   11, factor2, 12
factor1, 13, sell,        , factor1, 14
factor2, 15, factor1,   16, factor2, 17
sell,      , factor2,   18, factor1, 19
factor1, 20, ,            , factor2, 21,
factor2, 22, ,            , sell,
,          , ,            , factor1, 23
,          , ,            , factor2, 24
,          , ,            , factor1, 25
,          , ,            , factor2, 26

Ultimately, I would like I table structured like below.

time,   position,   factor,     value
time1,  buy,        factor1,    1
time1,  buy,        factor2,    4
time1,  buy,        factor1,    7
time1,  buy,        factor2,    10
time1,  buy,        factor1,    13
time1,  buy,        factor2,    15
time1,  sell,       factor1,    20
time1,  sell,       factor2,    22
time2,  buy,        factor1,    2
time2,  buy,        factor2,    5
time2,  buy,        factor1,    8
time2,  buy,        factor2,    11
time2,  sell,       factor1,    16
time2,  sell,       factor2,    18
time3,  buy,        factor1,    3
time3,  buy,        factor2,    6
time3,  buy,        factor1,    9
time3,  buy,        factor2,    12
time3,  buy,        factor1,    14
time3,  buy,        factor2,    17
time3,  buy,        factor1,    19
time3,  buy,        factor2,    21
time3,  sell,       factor1,    23
time3,  sell,       factor2,    24
time3,  sell,       factor1,    25
time3,  sell,       factor2,    26

I am able to extract the indices and then create respectively 'buy' and 'sell' list in R. But I am unsure whether this is the easiest approach (I have many such files, and would prefer a fast automatic method). I am also open to making the transformation i Python, rather than R.

# For each column find the index of buy, sell (and the corresponding empty cell)
idx = apply(data, 2, function(x) which(x %in% c("buy","sell",""))[1:3] )
# NA indicates that the empty cell is the last
idx[is.na(idx)] = nrow(data)

i = 0
buy = list( apply(idx, 2, function(x) {
  i <<- i+1
  data[seq(x[1]+1,x[2]),i]
}) )
i = 0
sell = list( apply(idx, 2, function(x) {
  i <<- i+1
  data[seq(x[2]+1,x[3]),i]
}) )

Body:
I decidd to combine the 3 sets of 2 columns first in one long format data set. Then fill in the position column by last known value carried forward (tidyr::fill), and filter out the rubbish, by filtering on the column value.

Here is the working example:

library(dplyr)
library(tidyr)

str <- "
time, time1, time,  time2,  time, time3
buy,       , buy,        ,  buy,
factor1,  1, factor1,    2, factor1,  3
factor2,  4, factor2,    5, factor2,  6
factor1,  7, factor1,    8, factor1,  9
factor2, 10, factor2,   11, factor2, 12
factor1, 13, sell,        , factor1, 14
factor2, 15, factor1,   16, factor2, 17
sell,      , factor2,   18, factor1, 19
factor1, 20, ,            , factor2, 21,
factor2, 22, ,            , sell,
,          , ,            , factor1, 23
,          , ,            , factor2, 24
,          , ,            , factor1, 25
,          , ,            , factor2, 26
"

strfile <- textConnection(str)

raw <- read.table(strfile, header = F, sep = ",", stringsAsFactors = F)

library(dplyr)
library(tidyr)
dt <- do.call(rbind, lapply(1:3, function(x) {
  p <- raw[,c(x*2-1,x*2)]
  names(p) <- c('factor', 'value')
  p$time <- x
  p
  })
)

dt %>%
  mutate(position = if_else(trimws(factor) %in% c('buy','sell'),as.character(factor),as.character(NA)),
         value = as.numeric(value)) %>%
  fill(position) %>% filter(!is.na(value))

Result:

factor value time position
1   factor1     1    1      buy
2   factor2     4    1      buy
3   factor1     7    1      buy
4   factor2    10    1      buy
5   factor1    13    1      buy
6   factor2    15    1      buy
7   factor1    20    1     sell
8   factor2    22    1     sell
9   factor1     2    2      buy
10  factor2     5    2      buy
11  factor1     8    2      buy
12  factor2    11    2      buy
13  factor1    16    2     sell
14  factor2    18    2     sell
15  factor1     3    3      buy
16  factor2     6    3      buy
17  factor1     9    3      buy
18  factor2    12    3      buy
19  factor1    14    3      buy
20  factor2    17    3      buy
21  factor1    19    3      buy
22  factor2    21    3      buy
23  factor1    23    3     sell
24  factor2    24    3     sell
25  factor1    25    3     sell
26  factor2    26    3     sell


问:
Android - chronometer start and stop
I want to create a chronometer which I can start and stop with one button. With my code below I just get a nullpointer exception. How can I avoid it, or set the two functions to the button anyway?</p>

```<code>public class MainActivity extends ActionBarActivity {
  Chronometer focus;
  Button start, stop, reset;
  long timeElapsed = SystemClock.elapsedRealtime() - focus.getBase();
  int x;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    timeElapsed = x;
    start = (Button) findViewById(R.id.button1);
    focus = (Chronometer) findViewById(R.id.chronometer1);

    start.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(x == 0){
            focus.start();
            }

            if(x != 0){
            focus.stop();
            }
        }
    });

}

}
</code>```

答:
You are using variables before they are initialized. 'focus' and 'x' are used before they are initialized. Use this code instead to avoid nullpointer exception:</p>

```<code>     public class MainActivity extends ActionBarActivity {
  Chronometer focus;
  Button start, stop, reset;
  long timeElapsed = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    start = (Button) findViewById(R.id.button1);
    focus = (Chronometer) findViewById(R.id.chronometer1);
    // to get the elapsed time use setonChronometerTickListener
    focus.setOnChronometerTickListener(new OnChronometerTickListener() {
         @Override
         public void onChronometerTick(Chronometer chronometer) {
             timeElapsed = SystemClock.elapsedRealtime() - focus.getBase();
         }
    });
    start.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(timeElapsed == 0){
            focus.setBase(SystemClock.elapsedRealtime());
            focus.start();
            }

            if(timeElapsed != 0){
        timeElapsed = 0;
            focus.stop();
            }
        }
    });

}
</code>```

Title: Android - chronometer start and stop

Body:
I want to create a chronometer which I can start and stop with one button. With my code below I just get a nullpointer exception. How can I avoid it, or set the two functions to the button anyway?

public class MainActivity extends ActionBarActivity {
  Chronometer focus;
  Button start, stop, reset;
  long timeElapsed = SystemClock.elapsedRealtime() - focus.getBase();
  int x;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    timeElapsed = x;
    start = (Button) findViewById(R.id.button1);
    focus = (Chronometer) findViewById(R.id.chronometer1);

    start.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(x == 0){
            focus.start();
            }

            if(x != 0){
            focus.stop();
            }
        }
    });

}

}

Body:
You are using variables before they are initialized. 'focus' and 'x' are used before they are initialized. Use this code instead to avoid nullpointer exception:

     public class MainActivity extends ActionBarActivity {
  Chronometer focus;
  Button start, stop, reset;
  long timeElapsed = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    start = (Button) findViewById(R.id.button1);
    focus = (Chronometer) findViewById(R.id.chronometer1);
    // to get the elapsed time use setonChronometerTickListener
    focus.setOnChronometerTickListener(new OnChronometerTickListener() {
         @Override
         public void onChronometerTick(Chronometer chronometer) {
             timeElapsed = SystemClock.elapsedRealtime() - focus.getBase();
         }
    });
    start.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(timeElapsed == 0){
            focus.setBase(SystemClock.elapsedRealtime());
            focus.start();
            }

            if(timeElapsed != 0){
        timeElapsed = 0;
            focus.stop();
            }
        }
    });

}